Путать о AngularJS раскрываемый и изолировать областей & Привязок
Я пытаюсь понять объем моделей и их привязки в отношении директив, которые имеют ограниченный объем.
Я понимаю, что ограничение области действия директивы означает, что контроллер.$область и директива.объем не то же самое. Однако я смущен тем, как размещение моделей либо в шаблоне директивы, либо в html влияет на привязку данных. Я чувствую, что мне не хватает чего-то очень фундаментального, и чтобы двигаться дальше, мне нужно понять этот.
Возьмите следующий код (скрипка здесь:http://jsfiddle.net/2ams6/)
JavaScript
var app = angular.module('app',[]);
app.controller('Ctrl',function($scope){
});
app.directive('testel', function(){
return {
restrict: 'E',
scope: {
title: '@'
},
transclude: true,
template: '<div ng-transclude>'+
'<h3>Template title: {{title}}</h3>' +
'<h3>Template data.title:{{data.title}}</h3>' +
'</div>'
}
});
HTML
<div ng-app='app'>
<div ng-controller="Ctrl">
<input ng-model="data.title">
<testel title="{{data.title}}">
<h3>Transclude title:{{title}}</span></h3>
<h3>Transclude data.title:{{data.title}}</h3>
</testel>
</div>
</div>
модель обновляется только {{title}}
внутри шаблона, и {{data.title}}
в Передача. почему бы и нет {{title}}
В передача, ни {{data.title}}
в шаблоне?
перемещение на вход в Передача вроде так (скрипка здесь: http://jsfiddle.net/eV8q8/1/):
<div ng-controller="Ctrl">
<testel title="{{data.title}}">
<input ng-model="data.title">
<h3>Transclude title: <span style="color:red">{{title}}</span></h3>
<h3>Transclude data.title: <span style="color:red">{{data.title}}</span></h3>
</testel>
</div>
теперь означает только transclude {{data:title}}
обновляется. почему бы и не шаблон {{title}}
или {{data.title}}
, ни включение {{title}}
?
и, наконец, перемещение ввода в шаблон, например, так (скрипка здесь:http://jsfiddle.net/4ngmf/2/):
template: '<div ng-transclude>' +
'<input ng-model="data.title" />' +
'<h3>Template title: {{title}}</h3>' +
'<h3>Template data.title: {{data.title}}</h3>' +
'</div>'
теперь означает, что только шаблон {{data.title}}
обновляется. опять же, почему не другие 3 привязки?
Я надеюсь, что есть что-то очевидное, глядя мне в лицо и я скучаю по ней. Если вы заставите меня это сделать, я куплю вам пива, или дам вам несколько очков, или что-то еще в этом роде. Большое спасибо.
3 ответа:
ваши скрипки создают три области:
- область, связанная с контроллером
Ctrl
из-заng-controller
- директива вышла за пределы области видимости, из-за
transclude: true
- директива изолировать область, из-за
scope: { ... }
в fiddle1, прежде чем вводить что-либо в текстовое поле, мы имеем следующее:
область 003-это область, связанная с контроллером. Так как мы не вводите в текстовое поле нет
data
собственность. В изолированной области 004 мы видим, что atitle
свойство было создано, но оно пусто. Он пуст, потому что родительская область не имеетdata.title
собственности.после ввода
my title
в текстовое поле, теперь у нас есть:область контроллера 003 теперь имеет новый
data
свойство объекта (именно поэтому он окрашен в желтый цвет), который имеетtitle
свойство теперь установлено вmy title
. Так как изолировать область свойстваtitle
является односторонней привязкой данных к интерполированному значениюdata.title
, Она также получает значениеmy title
(значение окрашено в желтый цвет, потому что оно изменилось).закодированная область прототипически наследуется от области контроллера, поэтому внутри закодированного HTML angular может следовать цепочке прототипов и находить
$scope.data.title
в родительской области (но$scope.title
не существует).область изоляции имеет доступ только к своим собственным свойствам, отсюда только свойство
title
.в fiddle2, перед вводом мы имеем ту же картину, что и в fiddle1.
после ввода
my title
:обратите внимание, где новый
data.title
свойство появилось -- на закодированной области. Область изоляции все еще ищетdata.title
на область контроллера, но его нет на этот раз, так что егоtitle
значение свойства остается пустой.в fiddle3, перед вводом у нас есть то же самое картина, как в fiddle1.
после ввода
my title
:обратите внимание, где новый
data.title
свойство появилось -- в области изоляции. Ни одна из других областей не имеет доступа к изолированной области, поэтому строкаmy title
больше нигде не появится.
обновление для Angular v1. 2:
С изменениями eed299a Угловое теперь очищает точки передача до transcluding, поэтому
Template title: ...
иTemplate data.title: ...
детали не будут отображаться, если вы не измените шаблон таким образом, чтоng-transclude
сам по себе, такие как:'<h3>Template title: <span style="color:red">{{title}}</span></h3>' + '<h3>Template data.title: <span style="color:red">{{data.title}}</span></h3>' + '<div ng-transclude></div>'
в обновлении ниже для Angular v1.3, это изменение шаблона было сделано.
обновление для Angular v1. 3+:
начиная с Angular v1.3, область transcluded теперь является дочерним элементом области изоляции директивы, а не дочерним элементом области контроллера. Итак, в fiddle1, прежде чем мы наберем что угодно:
изображения в этом обновлении рисуются с помощью Peri$scope инструмент, так что фотографии немного отличаются. Элемент
@
указывает, что у нас есть свойство изолировать область, которое использует@
синтаксис, а розовый фон означает, что инструмент не смог найти ссылку на предка для сопоставления (что верно, поскольку мы еще ничего не вводили в текстовое поле).после ввода
my title
в текстовое поле, теперь у нас есть:выделить свойства, которые используют
@
привязка всегда будет показывать результат интерполированной строки в области изоляции после@
символ. Peri$scope также смог найти это точное строковое значение в области предка, поэтому он также показывает ссылку на это свойство.в скрипке 2, Перед вводом мы имеем ту же картину, что и в скрипке 1.
после ввода
my title
:обратите внимание, где новый
data.title
свойство появилось -- на закодированной области. Область изоляции все еще ищетdata.title
на область контроллера, но его нет на этот раз, так что егоtitle
значение свойства остается пустой.в fiddle3, перед вводом мы имеем ту же картину, что и в fiddle1.
после ввода
my title
:обратите внимание, где новый
data.title
свойство появилось -- в области изоляции. Несмотря на то, что закодированная область имеет доступ к изолированной области через$parent
отношения, он не будет искать тамtitle
илиdata.title
-- он будет выглядеть только в области контроллера (т. е. он будет следовать прототипному наследованию), а область контроллера не имеет этих свойств.
после прочтения всех представленных ответов, включая фантастические схемы Марка, это мое понимание объема, и это наследование на мой вопрос. Я был бы признателен за комментарии о том, где эта диаграмма падает, чтобы я мог соответствующим образом обновить. Я надеюсь, что это просто дает другой взгляд на то, что Марк представил:
Ну спросил, Кстати! Надеюсь, мой ответ будет столь же красноречив..
ответ, как раскрываемый элементы, сделать их объем.
подводя итог, у вас есть две области:
- область действия контроллера, которая имеет
$scope.data.title
. (Неявно добавлено вашимinput
элемент)- область действия директивы, которая имеет
$scope.title
.при смене контроллера
$scope.data.title
, директивой$scope.title
также изменения.вы получили две секции HTML-код, раскрываемый шаблон. Что происходит, так это то, что закодированный HTML находится в контроллер область, и шаблон HTML находится в директивы объем. Поэтому раскрываемый HTML не знаю ничего о
title
, и область шаблона ничего не знает оdata.title
это именно то, что передача предназначалась для разрешить дочерние элементы директивы сохранить их родительскую область в этом случае объем контроллера. По дизайну, раскрываемый элементы не знают, что их в директивы, и поэтому не имеют доступа к сферы действия директивы.
Шаблоны директив, с другой стороны, будут иметь доступ только к области действия директивы.
Я немного изменил ваш код, чтобы сделать имена немного более ясными (та же функциональность, хотя)