Внутренний контент директивы с изолированными и неизолированными областями
Я нашел довольно странное поведение типа scope: true для внутреннего содержимого директивы:
<body ng-init="x=10">
<mydir>
{{x}}
</mydir>
</body>
поэтому {{x}} является внутренним контентом, а определение директивы:
.directive('mydir', function() {
return {
scope: {},
link: function(scope){
scope.x = 5;
}
};
});
Когда мы определяем область как изолированную (область: {}), она выводит {{x}} как 10, поэтому использует внешнюю область. Но когда мы создаем новую область действия для директивы ( scope: true), она будет использовать ее для внутреннего контента и вывода 5. Таким образом, для внутреннего содержимого для разных случаев используется несколько областей для внутреннего содержимого. Может ли кто-нибудь дать мне подсказку/ссылку на код/руководство для объяснения этой непоследовательности?
Здесь plnk играть с кодом.
UPD. Я понимаю, что такое наследование прототипа JavaScript. Я знаю разницу между типами областей действия. И моя цель - не отображать 5 вместо 10. Вопрос касается внутреннего шаблона, который в обоих случаях должен быть интерполирован с родительской областью, которая не имеет доступа к свойствам дочернего/изолированного.
Ответы
Ответ 1
A получил ответ от проблем angular:
https://github.com/angular/angular.js/issues/13845#issuecomment-174953398
И вот ответ на исходный код:
https://github.com/angular/angular.js/blob/eae0a1121ffcc636d760463105dcdc548ea47390/src/ng/compile.js#L2538-L2545
var scopeToChild = scope;
if (newIsolateScopeDirective && (newIsolateScopeDirective.template || newIsolateScopeDirective.templateUrl === null)) {
scopeToChild = isolateScope;
}
childLinkFn && childLinkFn(scopeToChild, linkNode.childNodes, undefined, boundTranscludeFn);
резюме:
В случае изолированного типа видимости область предоставляется ТОЛЬКО для шаблона директивы, но не для внутреннего содержимого.
Ответ 2
В исходном фрагменте кода {{x}}
не относится к <mydir>
. Вы должны определить шаблон для директивы.
// js
.directive('mydir', function() {
return {
template: '{{x}}',
scope: {},
link: function(scope){
scope.x = 5;
}
};
});
// html
<body ng-init="x=10">
<mydir></mydir>
</body>
Вот предварительный просмотр
Ответ 3
Что-то не так происходит. Если вы запустите свой код в Chrome с включенным Batarang, вы можете увидеть, когда scope: {}, что он действительно создает новую область, отличную от первой, полностью отключен и устанавливает переменную в 5. Но ваша интерполированная строка привязана к внешней области. Если вы установите область: истина, она также создаст новую область, унаследованную от внешнего, а интерполяция {{x}} будет правильно привязана. Я не думаю, что это параметр области действия в директиве, которая не работает, что-то с привязкой не работает.