范围不应该被隔离吗?

时间:2014-08-05 19:04:06

标签: javascript angularjs

我有两个简单的指令,它们在DOM中生成类似的元素。

  • 两者都有一个孤立的范围
  • 两者都有一个ng-click到显示消息的metod。
  • 一个人在html文件中声明了ng-click,并且触发了包含范围内的方法。
  • 另一个在指令模板中具有ng-click,并且单击会触发隔离范围中的方法

为什么不在隔离范围内触发方法?

这是Plunk

的Javascript

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.alertMessage = function(){
    alert('I live in mainController');
  }
});

app.directive('isolated', function(){
  return {
    scope: {},
    link: function(scope, element, attrs) {
      scope.alertMessage = function(){
        alert('I live in the isolated directive');
      };
    }
  };
});

app.directive('isolatedWithTemplate', function(){
  return {
    scope: {},
    replace: true,
    template: '<button ng-click="alertMessage()">Press me</button>',
    link: function(scope, element, attrs) {
      scope.alertMessage = function(){
        alert('I live in the isolated directive');
      };
    }
  };
});

HTML

<button isolated ng-click="alertMessage()">Press me</button>
<div isolated-with-template></div>

2 个答案:

答案 0 :(得分:1)

<button isolated ng-click="alertMessage()">Press me</button>

在这种情况下,ng-click独立于隔离指令,即使将html更改为

,它也会起作用
<button ng-click="alertMessage()">Press me</button>

所以上面的ng-click不适用于isolate指令,而是适用于控制器的范围......

ng-click的{​​{1}}正在指令范围内工作..

答案 1 :(得分:1)

(答案更新了@Edminsson指出的更正信息)

请参阅以下链接以了解范围 - 虽然链接不解释上述行为,但我的答案将尝试解释。

Understanding Scopes

下面将尝试解释为什么元素与'隔离'&#39;指令说&#39;我在mainController范围内&#39;而不是&#39;我在孤立的范围内。

注意两个DOM元素的顺序无关紧要,优先级对我们看到的内容都没有影响。

<div isolated-with-template></div>
<button  isolated ng-click="alertMessage()">No Template</button>

元素上的每个指令都是在父级的范围内编译的。 这意味着ng-click绑定到MainController中的scope函数。 isolate指令确实创建了一个新的隔离范围及其上的函数,但是ng-click已经绑定到mainController的函数对象$ scope.alertMessage()。

带有isolated-with-template的元素也会使用父作用域进行编译。但是当它遇到指令时它现在有一个模板。这被编译(确切地说是nodeLinkFn。有afterTemplateNodeLinkFn所以带有模板或templateUrls的指令将使用它)。此时,隔离范围具有来自隔离范围的函数alertMessage。还要知道MainController的alertMessage已经在所有这些之前在该范围上定义。

1)Angular首先处理DOM深度并向后链接

2)模板的根获得其直接范围

3)当多个指令在元素上请求范围时,只能获得一个范围

scope = true会怎样?

this plnkr中,您会注意到该指令不再说“我在主控制器中”。

scope:true,

您实际上正在获得全新的儿童范围。当创建链接功能时,角度知道这个范围是一个全新的范围。

隔离范围的一个技巧 尝试分配模板:&#39; &#39;,并替换:true 并且你有自己独立的范围。

Isolated scope trick using another example

.directive("client", function() {
    return {
      restrict: "A",
      template: '  ',//notice extra spaces
      replace: true,//notice this
      scope: {
        name: "@name",
        client: "=client"
      }
    };
  });