AngularJS: двухстороннее связывание данных завершается с ошибкой, если элемент имеет ngModel и директиву с локальной областью
Проблема показана здесь:
http://jsfiddle.net/ews7S/
<input type="text" ng-model="testModel" dir="123">
Когда элемент привязан к модели в области контроллера, и вы также добавляете директиву к элементу, у которого есть собственная локальная область, то изменения в модели изменяются только в области директив.
Ответы
Ответ 1
Решение состоит в том, чтобы добавить это в директиву:
scope: {testModel: '=ngModel'},
Смотрите здесь:
http://jsfiddle.net/ews7S/1/
Почему это работает, потому что '=' устанавливает двунаправленную привязку между локальным свойством scope и свойством родительской области (см. docs: http://docs.angularjs.org/guide/directive в разделе "Объект определения директивы" ).
Ответ 2
Альтернативным решением является использование объекта для модели, а не примитива. Затем новая область действия наследует (прототипно) ссылку на объект, а не копию примитивного значения:
$scope.model = { testProp: "444" };
<input type="text" ng-model="model.testProp" dir="123">
<input type="text" ng-model="model.testProp">
document.getElementById("out").innerHTML = scope.model.testProp;
http://jsfiddle.net/mrajcok/awfU5/
С помощью примитива, такого как $scope.testModel, свойство testModel области директивы получает копию значения родительской переменной testModel. Изменения в одном не влияют на другие.
С объектом, таким как $scope.model, как родительская область, так и область действия директивы имеют ссылку на один и тот же (один) объект. Изменения влияют на один и тот же объект.
Другим (хрупким) решением является использование родительского свойства undocumented $(внесите эти изменения в скрипт вопроса):
<input type="text" ng-model="$parent.testModel" dir="123">
document.getElementById("out").innerHTML = scope.$parent.testModel;
Обратите внимание, что использование $parent
является хрупким решением, поскольку использование $parent
зависит от структуры DOM. Например, если был добавлен другой контроллер (явно или неявно с помощью другой директивы Angular) между родительским и дочерним (теперь внуком), нам тогда понадобится использовать $parent.$parent.testModel
.