我一直在使用1.3的beta版本,现在转移到1.3.1后,我注意到一个问题,通过检查所有早期版本,我看到它似乎已经在1.3.0 rc1中启动了.
我有这样的代码:
- <select ng-model="home.modal.topicId"
- ng-change="ctrl.modalTopicChanged()"
- ng-options="item.id as item.name for item in home.modal.option.topics.data"
- ng-required="true">
- <option style="display: none;" value="">Select Topic</option>
- </select>
在rc1之前,首次显示表单时未触发ng-change.现在它被一个未定义的home.modal.topicId解雇了.这对我来说是一个突破性的变化,但它没有在突破性变化部分提及,我想知道它是否是一个尚未被注意到的错误.
这是生成的堆栈跟踪:
- TypeError: Cannot read property 'dataMap' of undefined
- at AdminProblemController.modalTopicChanged (http://127.0.0.1:17315/Content/app/admin/controllers/ProblemController.js:109:114)
- at $parseFunctionCall (http://127.0.0.1:17315/Scripts/angular.js:11387:18)
- at Scope.$get.Scope.$eval (http://127.0.0.1:17315/Scripts/angular.js:13276:28)
- at http://127.0.0.1:17315/Scripts/angular.js:19888:13
- at http://127.0.0.1:17315/Scripts/angular.js:19499:9
- at forEach (http://127.0.0.1:17315/Scripts/angular.js:331:20)
- at $$writeModelToScope (http://127.0.0.1:17315/Scripts/angular.js:19497:5)
- at writeToModelIfNeeded (http://127.0.0.1:17315/Scripts/angular.js:19490:14)
- at http://127.0.0.1:17315/Scripts/angular.js:19484:9
- at validationDone (http://127.0.0.1:17315/Scripts/angular.js:19420:9)
我在这里注意到的是一个新函数:writeToModelIfNeeded
当我查看更改日志差异时,在检查所有更改和行号时,我找不到提及此功能的任何内容.
我想就此提出一些建议.首先是可以找到导致添加writeToModelIfNeeded的更改,其次是选择框的正确功能.我认为整个想法是只有在定义模型值时才会触发ng-change.
这里参考的是新代码的区域,似乎已经添加了1.3.0 rc.1
- **
- * @ngdoc method
- * @name ngModel.NgModelController#$commitViewValue
- *
- * @description
- * Commit a pending update to the `$modelValue`.
- *
- * Updates may be pending by a debounced event or because the input is waiting for a some future
- * event defined in `ng-model-options`. this method is rarely needed as `NgModelController`
- * usually handles calling this in response to input events.
- */
- this.$commitViewValue = function() {
- var viewValue = ctrl.$viewValue;
- $timeout.cancel(pendingDebounce);
- // If the view value has not changed then we should just exit,except in the case where there is
- // a native validator on the element. In this case the validation state may have changed even though
- // the viewValue has stayed empty.
- if (ctrl.$$lastCommittedViewValue === viewValue && (viewValue !== '' || !ctrl.$$hasNativeValidators)) {
- return;
- }
- ctrl.$$lastCommittedViewValue = viewValue;
- // change to dirty
- if (ctrl.$pristine) {
- ctrl.$dirty = true;
- ctrl.$pristine = false;
- $animate.removeClass($element,PRISTINE_CLASS);
- $animate.addClass($element,DIRTY_CLASS);
- parentForm.$setDirty();
- }
- this.$$parseAndValidate();
- };
- this.$$parseAndValidate = function() {
- var parserValid = true,viewValue = ctrl.$$lastCommittedViewValue,modelValue = viewValue;
- for(var i = 0; i < ctrl.$parsers.length; i++) {
- modelValue = ctrl.$parsers[i](modelValue);
- if (isUndefined(modelValue)) {
- parserValid = false;
- break;
- }
- }
- if (isNumber(ctrl.$modelValue) && isNaN(ctrl.$modelValue)) {
- // ctrl.$modelValue has not been touched yet...
- ctrl.$modelValue = ngModelGet();
- }
- var prevModelValue = ctrl.$modelValue;
- var allowInvalid = ctrl.$options && ctrl.$options.allowInvalid;
- if (allowInvalid) {
- ctrl.$modelValue = modelValue;
- writeToModelIfNeeded();
- }
- ctrl.$$runValidators(parserValid,modelValue,viewValue,function() {
- if (!allowInvalid) {
- ctrl.$modelValue = ctrl.$valid ? modelValue : undefined;
- writeToModelIfNeeded();
- }
- });
- function writeToModelIfNeeded() {
- if (ctrl.$modelValue !== prevModelValue) {
- ctrl.$$writeModelToScope();
- }
- }
- };
- this.$$writeModelToScope = function() {
- ngModelSet(ctrl.$modelValue);
- forEach(ctrl.$viewChangeListeners,function(listener) {
- try {
- listener();
- } catch(e) {
- $exceptionHandler(e);
- }
- });
- };