我正在使用在服务器呈现HTML上使用角度的Web应用程序。
我正在尝试使用一段呈现的HTML作为可重用的组件(指令),因此我在返回的HTML中的相应标记上附加了一个属性指令。该指令需要具有独立的范围,并且它还将包含子指令,该指令应该是此隔离指令中的子范围。
不幸的是,angular不会从返回的HTML中创建具有适当范围层次结构的指令。孤立范围内的子指令是孤立范围的兄弟(而不是子节点)。现在,如果我更改这些指令以使用客户端模板,它可以正常工作。因此,似乎angular不喜欢从服务器生成的HTML构造此表单的指令。
为了更好地说明我的问题,我创建了一些傻瓜 - 一个正常工作(客户端模板),一个工作不正确(服务器呈现HTML)。
的index.html
<body>
<div isolate-dir>
Content from the server
<div child-dir>
More content from the server: <span ng-bind="testVar">server data</span>
</div>
</div>
</body>
的script.js
angular.module('test', []);
angular.module('test').directive('isolateDir', function() {
return {
restrict: 'A',
scope: {},
link: function(scope, element, attr) {
console.log('isolate dir scope [' + scope.$id + ' -> ' + scope.$parent.$id + ']');
}
}
});
angular.module('test').directive('childDir', function() {
return {
restrict: 'A',
scope: true,
link: function(scope, element, attr) {
console.log('child dir scope [' + scope.$id + ' -> ' + scope.$parent.$id + ']');
scope.testVar = "client data";
}
}
});
输出
child dir scope [3 -> 1]
isolate dir scope [2 -> 1]
的index.html
<body>
<div isolate-dir></div>
</body>
的script.js
angular.module('test', []);
angular.module('test').directive('isolateDir', function() {
return {
restrict: 'A',
scope: {},
link: function(scope, element, attr) {
console.log('isolate dir scope [' + scope.$id + ' -> ' + scope.$parent.$id + ']');
},
template: "Content from the server <div child-dir></div>"
}
});
angular.module('test').directive('childDir', function() {
return {
restrict: 'A',
scope: true,
link: function(scope, element, attr) {
console.log('child dir scope [' + scope.$id + ' -> ' + scope.$parent.$id + ']');
scope.testVar = "client data";
},
template: "More content from the server: <span ng-bind='testVar'>server data</span>"
}
});
输出
child dir scope [3 -> 2]
isolate dir scope [2 -> 1]
当运行数据并观察控制台输出时,您可以看到范围层次结构在客户端模板化版本中是正确的,在服务器呈现版本中是不正确的。
为什么范围层次结构与服务器呈现的内容不一致,解决此问题的最佳方法是什么?
答案 0 :(得分:2)
好消息是这与“服务器”渲染无关。
问题来自您对指令的理解。隔离指令(isolate-dir
)确实具有影响其模板和控制器的隔离范围。但是,HTML层次结构与Angular范围层次结构没有关系:只有<div isolate-dir>
具有隔离范围,但不是所有子元素。
如果您希望子元素从父div
的范围继承,您应该将这些子元素放入隔离指令的模板中(在第一个示例中完成,因此它可以工作),或者传播使用transclusion
函数的link
参数将父范围扩展到其内部元素。
这是一个使用这种方法的傻瓜:
plnkr.co/edit/n0ws7pPqOS8dt6IMKYMl?p=info
如果这仍然让您感到困惑,您可以在此处详细了解它:
http://angular-tips.com/blog/2014/03/transclusion-and-scopes/