Angularjs: двухсторонняя привязка не работает в включенном шаблоне
Я думаю, что я пропустил что-то простое (и важное) здесь. Я использую включенный шаблон, который содержит вход, который отображается на некоторое значение:
<div ng-controller="Ctrl">
<div ng-include src="'template.html'"></div>
</div>
<!-- template -->
<script type="text/ng-template" id="template.html">
<input ng-model="testvalue" />
</script>
Контроллер:
function Ctrl($scope) {
$scope.testvalue= "initial value";
}
Предупреждение значения $scope.testvalue всегда показывает начальное значение, а не обновленное значение (при вводе ввода). Помоги мне Оби-Вану. Вы - наша единственная надежда.
Fiddle: http://jsfiddle.net/h5aac/
Ответы
Ответ 1
Это слишком распространенная привязка к примитиву, а не к объекту. Значение строки передается, а не ссылка на объект. Если вы используете объект вместо примитива, он отлично работает. Что-то вроде этого в вашем объеме.
$scope.foo = {testvalue: "initial value"};
См. http://jsfiddle.net/h5aac/2/
также:
Использование` ng-model` в директиве transcluded в AngularJS
проблема с привязкой к директиве в ngRepeat
AngularJS - обновление значения области с асинхронным ответом
Я уверен, что есть еще...
Ответ 2
Альтернативой ссылаться на свойство объекта в родительской области является использование $parent для доступа к примитиву в родительской области:
<input ng-model="$parent.testvalue" />
ng-include создает дочернюю область. Этот объем прототипически наследуется от родительской области Ctrl. Вот как работают 3 варианта:
- $parent.testvalue привязывает модель к свойству в родительской области
- testvalue сам по себе связывает модель с новым свойством, которое будет создано в области дочерних объектов. Это свойство "теней/скрывает" свойство родительской области с тем же именем.
- foo.testvalue(например, см. ответ @dnc253) также связывает модель с родительским свойством. Он работает следующим образом: Javascript не видит/не находит "foo" в области содержимого, поэтому он ищет его в родительской области (из-за прототипического наследования) и находит его там.
Чтобы увидеть, как выглядит область доступа к ребенку, используйте свою оригинальную скрипту и добавьте этот код в свой шаблон где-нибудь:
<a ng-click="showScope($event)">show scope</a>
И добавьте этот код в свой Ctrl:
$scope.showScope = function(e) {
console.log(angular.element(e.srcElement).scope());
}
Прежде чем вводить текстовое поле, нажмите ссылку "показать область". В консоли (я использую Chrome) вы можете расширить область "Ребенок" и увидеть, что она еще не содержит свойства testvalue (что мне кажется удивительным, потому что я не знаю, как он отображает "начальное значение", в текстовом поле). Вы можете развернуть $parent, и вы увидите свойство testvalue - свойство с этим именем отображается только в родительской области на данный момент.
Теперь очистите консоль, введите в текстовое поле и снова нажмите ссылку "показать область". Вы увидите, что область "Child" теперь имеет новое свойство testvalue. Он скрывает/скрывает родительское свойство. Таким образом, вещи в области дочерних объектов видят свойство testvalue дочернего объекта, а объекты в родительской области - свойство testvalue родительской области.
Обновление: FYI, я недавно написал обширный ответ/статью о прототипном наследовании области, которая более подробно объясняет приведенные выше концепции с большим количеством фотографий: Каковы нюансы объема прототипа/прототипного наследования в AngularJS?