2014-11-04 20 views
7

Używam wersji beta 1.3 i teraz po przejściu do wersji 1.3.1 zauważam problem, który sprawdzając wszystkie wcześniejsze wersje, wydaje się, że zaczął się w 1.3 .0 rc1.Problemy z ngChange dla <select> po 1.3.0 rc0

mam kod jak poniżej:

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

Przed RC1 NG-zmiana była nie wyrzuceniu gdy formularz był pierwszy wyświetlany. Teraz jest uruchamiany z home.modal.topicId z undefined. Jest to dla mnie przełomowa zmiana, ale nie jest to wspomniane w dziale "łamanie zmian" i zastanawiam się, czy to błąd, którego jeszcze nie zauważyłem.

Oto ślad stosu produkowane:

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) 

Co Zauważam tu jest nowa funkcja: writeToModelIfNeeded

Kiedy patrzę na różnicach dziennika zmian nie mogę znaleźć żadnej wzmianki o tej funkcji wprowadzanych kiedy sprawdzam wszystkie zmiany i numery linii.

Chciałbym uzyskać kilka porad na ten temat. Po pierwsze jest to możliwe, aby znaleźć zmianę, która spowodowała dodanie writeToModelIfNeeded następnie po drugie jest to poprawna funkcjonalność dla pola wyboru. Pomyślałem, że chodzi o to, że zmiana ng będzie wyzwalana tylko wtedy, gdy zdefiniowana zostanie wartość modelu.

Dla odniesienia tu jest obszar nowego kodu, który wydaje się być dodany 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); 
     } 
    }); 
    }; 
+0

Możesz próbowano tworzenia jsfiddle z a przełączyć na 1,2x i 1.3x? – John

+3

Nie mogę powtórzyć tego problemu, ** [patrz ten plunker] (http://plnkr.co/edit/KMIOZx7pV4OYmhk1XayE?p=preview) **. Czy mógłbyś podzielić się zmodyfikowaną wersją tego plunkera, która powiela to zagadnienie? Dzięki! – Josep

+0

Zajrzę do tego plunkera i zobaczę, czy mogę znaleźć różnice między tą implementacją a moją. Dzięki –

Odpowiedz

5

udało mi się odtworzyć problem w ten sposób. Nie widząc kontrolera choć nie wiem, czy to samo:

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

Co się tu dzieje jest to, że kątowa mówi null jest nieprawidłowy stosunek więc domyślnie ustawia go do niezdefiniowane. Można rozwiązać ten problem przez ustawienie go na „nieokreślony” lub dodanie tego do swojej HTML:

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

również testowanego Josep plunker i zmiana tej wartości na null również spowodowane ngChange ognia

Powiązane problemy