Angular JS: получить ng-модель с ng-change
У меня есть следующий HTML
<select ng-model="country" ng-options="c.name for c in countries" ng-change="filterByCountry"></select>
Это происходит от следующего объекта со списком стран
$scope.countries = [{name:Afeganistão, country:AF}, {name:África do Sul, country:ZA}, name:Albânia, country:AL}, {name:Alemanha, country:DE}, {name:Andorra, country:AD} ...];
Когда я меняю свое выпадающее значение, я ожидал обновления моей модели ($ scope.country) внутри функции filterByCountry, но это не так. Что мне здесь не хватает?
Ответы
Ответ 1
Обработчик ng-change
запускается до фактического обновления ng-model
. Если вы хотите, чтобы filterByCountry
запускался каждый раз при изменении $scope.country
(а не только при изменении выпадающего списка), вы должны использовать следующее:
$scope.$watch('country', filterByCountry);
Я всегда считаю более полезным реагировать на изменения в моих $scope
, а не в DOM-событиях, когда это возможно.
Ответ 2
Просто для всех, кто придет сюда,
ng-change
фактически вызывается после того, как значение модели было установлено.
Почему?
Посмотрим, когда это называется.
Из angular исходный код ng-change
- это просто директива атрибута с этим объектом определения директивы (DDO).
{
restrict: 'A',
require: 'ngModel',
link: function(scope, element, attr, ctrl) {
ctrl.$viewChangeListeners.push(function() {
scope.$eval(attr.ngChange);
});
}
}
Отсюда видно, что директива ng-change
очень проста. Все, что ng-change='<expr>'
делает, это добавить функцию в конец $viewChangeListeners
, которая оценивает <expr>
через $scope. $Eval.
OK... поэтому, когда вызываются ViewChangeListeners?
Хорошо, если мы посмотрим на документацию для ngModel.NgModelController:
новое значение будет применено к $modelValue, а затем выражение, указанное в атрибуте ng-model. Наконец, все зарегистрированные прослушиватели изменений в списке $viewChangeListeners называются.
Таким образом, viewChangeListener для ngChange будет вызываться после того, как значение будет применено к $modelValue
. Следовательно, обратный вызов будет вызван после установки модели.
Также обратите внимание, что во всех версиях angular это поведение одинаково. Определение для ng-change
не изменилось с момента v1.2.
Ответ 3
Как указал Джеймс Лоусон,
ng-change на самом деле вызывается после установки значения модели.
И если вы все еще спрашиваете
Теперь, почему я вижу противоположное поведение?
Тогда вы должны знать, что $ scope является прототипом, унаследованным от его родителя, и если ваша переменная области видимости - это просто простой тип (строка, логическое значение и т.д.), То она будет перезаписана в дочерней области значением, которое было установлено с помощью ng- модельная директива
Чтобы увидеть, где создается дочерняя область (на каком элементе DOM), вы можете открыть инструменты разработчика и найти class="ng-scope"
для элемента