Директива Angular: использование ng-модели в пределах области выделения

У меня возникли проблемы с разработкой того, как я могу определить настраиваемую директиву, которая:

  • Использует область выделения и
  • Использует директиву ng-model в новой области внутри своего шаблона.

Вот пример:

HTML:

<body ng-app="app">
  <div ng-controller="ctrl">
    <dir model="foo.bar"></dir>
    Outside directive: {{foo.bar}}
  </div>
</body>

JS:

var app = angular.module('app',[])
  .controller('ctrl', function($scope){
    $scope.foo = { bar: 'baz' };
  })
  .directive('dir', function(){
    return {
      restrict: 'E',
      scope: {
        model: '='
      },
      template: '<div ng-if="true"><input type="text" ng-model="model" /><br/></div>'
    }
  });

Требуемое поведение здесь заключается в том, что входное значение привязано к свойству внешней области foo.bar, через свойство директивы (изолировать) scope model. Этого не происходит, потому что директива ng-if в шаблоне, охватывающем div, создает новую область видимости, поэтому она обновляет область model, а не область действия директивы. Обычно вы решаете эти проблемы с ng-моделью, убедившись, что в выражении есть точка, но я не вижу никакого способа сделать это здесь. Я задавался вопросом, могу ли я использовать что-то вроде этого для моей директивы:

{
  restrict: 'E',
  scope: {
    model: {
      value: '=model'
    }
  },
  template: '<div ng-if="true"><input type="text" ng-model="model.value" /><br/></div>'
}

но это не работает...

Plunker

Ответ 1

Вы правы - ng-if создает дочернюю область, которая вызывает проблему, когда текст вводится во входном текстовом поле. Он создает теневое свойство с именем "модель" в дочерней области, которое является копией родительской переменной области с тем же именем - эффективно нарушая привязку двухсторонней модели.

Исправление для этого просто. В шаблоне укажите префикс $parent:

  template: '<div ng-if="true">
                   <input type="text" ng-model="$parent.model" /><br/>
             </div>'

Это гарантирует, что он разрешит "модель" из $parent scope, которую вы уже установили для привязки двухсторонней модели через изолированную область.

В конце концов, '.' в ng-модели экономит день. Мне полезно подумать обо всем, что осталось от точки, как способ для Angular разрешить свойство через наследование сферы. Без точки разрешение свойства становится проблемой только при назначении переменных области (в противном случае поиск выполняется нормально, включая выражения для привязки только для чтения {{model}}).

Ответ 2

ng-if создает дополнительную область наследования с прототипом, поэтому ng-model="model" связывается с унаследованным свойством новой области действия, а не с 2-сторонним связыванием свойства области действия.

Измените его на ng-show, и он будет работать.

Вы можете использовать небольшое расширение Firebug, которое я написал для проверки областей angular.