Связанный элемент внутри ngIf не обновляет привязку
Я написал директиву angularjs.
в этом шаблоне директивы я добавил директиву ngIf, и внутри нее я отображаю вход, связанный с моей областью директивы.
<div ng-if="bool"><input ng-model="foo"></div>
Я заметил после многих проб и ошибок, что директива ngIf заставляет модель не обновляться при изменении входного текста. Если я изменю его на ngShow, все будет работать так, как ожидалось.
Я ищу объяснение этой разницы
Я создал jsfiddle здесь
Ответы
Ответ 1
Это происходит потому, что ngIf создает новую дочернюю область, поэтому, если вы хотите привязываться к той же области, что и другие входы, мы можем перейти на один уровень вниз с $parent. Проверьте здесь, чтобы больше узнать о наследовании области.
angular.module('testApp', [])
.directive('testDir', function () {
return {
restrict: 'A',
template: '<input ng-model="foo"><input ng-model="foo">' +
'<div ng-if="bool"><input ng-model="$parent.foo"></div>',
link: function (scope, elem, attrs) {
scope.foo = "bar";
scope.bool = true;
}
}
});
Взгляните на новый jsfiddle
Ответ 2
Это происходит потому, что вы используете примитив в области видимости.
ngIf
создает новую дочернюю область, и она меняет значение из родительской области.
Вместо этого используйте текстовую нотацию:
<div ng-if="bool"><input ng-model="data.foo"></div>
Наследование областей обычно является простым, и вам часто даже не нужно знать, что это происходит... пока вы не попробуете привязку двухсторонней привязки (т.е. элементы формы, ng-model) к примитиву (например, число, string, boolean), определенный в родительской области изнутри области содержимого.
Это не работает так, как многие люди ожидают, что он должен работать. Случается, что дочерняя область получает свое собственное свойство, которое скрывает/затеняет родительское свойство с тем же именем. Это не то, что делает AngularJS - так работает прототипное наследование JavaScript.
Новые разработчики AngularJS часто не понимают, что ng-repeat, ng-switch, ng-view и ng-include все создают новые дочерние области, поэтому проблема часто возникает, когда задействованы эти директивы,
Эту проблему с примитивами можно легко избежать, следуя "наилучшей практике" всегда иметь "." . в ваших ng-моделях.
Ответ 3
Определить foo как объект со свойствами. Все это связано с прототипным наследованием javascript. См. Измененный jsfiddle.
angular.module('testApp', [])
.controller('MyController',function($scope){
$scope.foo = {bool: true};
})
.directive('testDir', function () {
return {
restrict: 'A',
template: '<input ng-model="foo.x"><input ng-model="foo.x"><div ng-if="foo.bool"><br/>changing me does not update the other inputs because i am in an ngIf if in ngShow all works just fine<input ng-model="foo.x"></div>',
link: function (scope, elem, attrs) {
scope.foo.x = "bar";
scope.foo.bool = true;
}
}
});
Подробную информацию см. в этом видео.