Подтвердить что ты не робот

Связанный элемент внутри ngIf не обновляет привязку

Я написал директиву angularjs. в этом шаблоне директивы я добавил директиву ngIf, и внутри нее я отображаю вход, связанный с моей областью директивы.

<div ng-if="bool"><input ng-model="foo"></div>

Я заметил после многих проб и ошибок, что директива ngIf заставляет модель не обновляться при изменении входного текста. Если я изменю его на ngShow, все будет работать так, как ожидалось.

Я ищу объяснение этой разницы

Я создал jsfiddle здесь

4b9b3361

Ответ 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;       
      }
    }
  });

Подробную информацию см. в этом видео.