Problems with ngChange for <select> after 1.3.0 rc0

I am using beta version 1.3, and now, having switched to 1.3.1, I noticed a problem which, checking all earlier versions, I see that it started with 1.3.0 rc1 .

I have a code like this:

<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> 

Prior to rc1, the ng change was not triggered when the form showed first . Now it starts using home.modal.topicId undefined . This change is for me, but it is not mentioned in the section on changes, and I wonder if this is a mistake that remains to be noticed.

Here is the stack trace created:

 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) 

What I see here is a new feature: writeToModelIfNeeded

When I look at the differences in the change log, I cannot find mention of this function that appears when I check all changes and line numbers.

I would like some advice on this. Firstly, you can find the change that caused the addition of writeToModelIfNeeded, and secondly, this is the correct functionality for the selection window. I thought the whole idea was that ng-change would only work when determining the model value.

For reference, here is a region of new code that seems to have been added since 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); } }); }; 
+7
angularjs
source share
1 answer

I was able to reproduce your problem by doing this. Not seeing my controller, although not sure the same thing:

  this.modal = { topicId:null, option:{ topics:{ data:[{id:1,name:'item1'},{id:2,name:'item2'}] } } }; 

What happens here is that angular says that null is an invalid value, so it defaults to undefined. You can fix this by setting it to "undefined" or by adding this to your html:

 ng-model-options="{allowInvalid:true}" 

also tested the Josep plunger and changed this value to null, also called ngChange to run

+5
source share

All Articles