我一直在使用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); } }); };