Angular是使用服务器呈现的内容不正确地确定隔离指令

时间:2015-03-10 21:39:39

标签: angularjs

我正在使用在服务器呈现HTML上使用角度的Web应用程序。

我正在尝试使用一段呈现的HTML作为可重用的组件(指令),因此我在返回的HTML中的相应标记上附加了一个属性指令。该指令需要具有独立的范围,并且它还将包含子指令,该指令应该是此隔离指令中的子范围。

不幸的是,angular不会从返回的HTML中创建具有适当范围层次结构的指令。孤立范围内的子指令是孤立范围的兄弟(而不是子节点)。现在,如果我更改这些指令以使用客户端模板,它可以正常工作。因此,似乎angular不喜欢从服务器生成的HTML构造此表单的指令。

为了更好地说明我的问题,我创建了一些傻瓜 - 一个正常工作(客户端模板),一个工作不正确(服务器呈现HTML)。

Server Rendered Plunker

的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]

Client Templating Plunker

的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]

当运行数据并观察控制台输出时,您可以看到范围层次结构在客户端模板化版本中是正确的,在服务器呈现版本中是不正确的。

为什么范围层次结构与服务器呈现的内容不一致,解决此问题的最佳方法是什么?

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/