angularjs - Angular 使用服务器呈现的内容不正确地限定隔离指令的范围

标签 angularjs

我正在开发一个在服务器呈现的 HTML 之上使用 Angular 的 Web 应用程序。

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

不幸的是,angular 没有从返回的具有适当范围层次结构的 HTML 创建指令。隔离范围内的子指令是隔离范围的兄弟指令(而不是子指令)。现在,如果我将这些指令更改为使用客户端模板,它就可以正常工作。所以看起来 Angular 不喜欢从服务器生成的 HTML 构建这种形式的指令。

为了更好地说明我的问题,我创建了几个 plunkers - 一个工作正常(客户端模板),一个工作不正常(服务器呈现 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>

脚本.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>

脚本.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]

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

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

最佳答案

好消息是这与“服务器”渲染与否无关。

问题出在你对指令的理解上。 isolated 指令 ( isolate-dir ) 确实会有一个独立的作用域,它会影响它的模板和 Controller 。然而,HTML 层次结构与 Angular 范围层次结构没有关系:只有 <div isolate-dir>。将有一个独立的作用域,但不是它所有的子元素

如果您希望子元素继承父元素的范围div ,您应该将这些子项放入隔离指令的模板中(这在您的第一个示例中完成,因此有效),或者使用 transclusion 将父范围传播到其内部元素。给 link 的参数功能。

这是一个使用这种方法的 plunkr:

plnkr.co/edit/n0ws7pPqOS8dt6IMKYMl?p=info

如果这仍然让您感到困惑,您可以在这里阅读更多相关信息:

http://angular-tips.com/blog/2014/03/transclusion-and-scopes/

关于angularjs - Angular 使用服务器呈现的内容不正确地限定隔离指令的范围,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28974583/

相关文章:

javascript - 从 url 获取路由参数

javascript - 为什么在 $rootScope.$on 中需要 $rootScope.$apply?

angularjs - ng-repeat 的简单单向绑定(bind)?

javascript - 将 Angular 表达式替换为字符串中的静态值

AngularJS:ng-点击 img?使用 jQuery 操作图像(类似于画廊)?

javascript - 具有 "controller as"语法的动态 Controller

javascript - 通过jsPDF的addHTML向PDF添加多个元素

html - 背景图片 Z-index

javascript - Promise.all() 返回意外值

javascript - 如果表有行,则在 angularjs 中显示表