Javascript 为什么可以';不能在具有隔离作用域的指令模板中访问$rootScope吗?

Javascript 为什么可以';不能在具有隔离作用域的指令模板中访问$rootScope吗?,javascript,angularjs,angularjs-directive,Javascript,Angularjs,Angularjs Directive,使用隔离作用域时,指令的模板似乎无法访问控制器('Ctrl')$rootScope变量,但该变量确实出现在指令的控制器中。我理解为什么控制器('Ctrl')$scope变量在隔离作用域中不可见 HTML: 访问变量时没有隔离作用域-如注释隔离作用域行所示: // scope: {}, 您可以使用$root.blah html <label ng-click="test($root.blah)">Click</label> 1) 由于控制器Ctrl

使用隔离作用域时,指令的模板似乎无法访问控制器('Ctrl')$rootScope变量,但该变量确实出现在指令的控制器中。我理解为什么控制器('Ctrl')$scope变量在隔离作用域中不可见

HTML:

访问变量时没有隔离作用域-如注释隔离作用域行所示:

        // scope: {},

您可以使用
$root.blah

html

 <label ng-click="test($root.blah)">Click</label>
1) 由于控制器Ctrl和指令控制器中的隔离作用域
$scope
,因此控制器不引用相同的作用域-假设Ctrl中有作用域1,指令中有作用域2

2) 由于隔离作用域scope2的原因,不原型继承自
$rootScope
;因此,如果您定义
$rootScope.blah
,就不可能在scope2中看到它

3) 您可以在指令模板中访问的是scope2

如果我总结一下,这里是继承模式

    _______|______
    |            |
    V            V
$rootScope     scope2
    |
    V
  scope1


$rootScope.blah
> "Hello"
scope1.blah
> "Hello"
scope2.blah
> undefined

通常,应该避免使用
$rootScope
存储需要在控制器和指令之间共享的值。这就像在JS中使用globals一样。改用服务:

常量(或值…用法类似):

.constant('blah', 'blah')
.factory('BlahFactory', function() {
    var blah = {
        value: 'blah'
    };

    blah.setValue = function(val) {
      this.value = val;
    };

    blah.getValue = function() {
        return this.value;
    };

    return blah;
})

工厂(或服务或提供商):

.constant('blah', 'blah')
.factory('BlahFactory', function() {
    var blah = {
        value: 'blah'
    };

    blah.setValue = function(val) {
      this.value = val;
    };

    blah.getValue = function() {
        return this.value;
    };

    return blah;
})

这是一个演示如何使用这两种方法之一的例子。我知道这是一个老问题。但这并不能满足我关于为什么隔离作用域不能访问$rootscope中的属性的调查

所以我在有角度的库中挖掘发现-

$new: function(isolate) {
  var ChildScope,
      child;

  if (isolate) {
    child = new Scope();
    child.$root = this.$root;
    child.$$asyncQueue = this.$$asyncQueue;
    child.$$postDigestQueue = this.$$postDigestQueue;
  } else {

    if (!this.$$childScopeClass) {
      this.$$childScopeClass = function() {
        // blah blah...
      };
      this.$$childScopeClass.prototype = this;
    }
    child = new this.$$childScopeClass();
  }

这是angular在创建新范围时调用的函数。这里很清楚,任何隔离作用域都不是典型地继承根作用域。相反,只有根范围作为属性“$root”添加到新范围中。因此,我们只能从新隔离作用域中的$root属性访问rootscope的属性。

您是否尝试将$rootscope注入指令中<代码>指令('myTemplate',函数($rootScope){…})?@MarcKline刚刚尝试过,但没有成功。是否有理由使用服务不足以满足您的目的?@Kalyan-我个人认为$rootScope应该只用于事件和工厂,用于将数据传递给指令。一个原因是使用$rootScope就像使用全局变量,这并不理想。此外,工厂可以是一个定义良好的包装器,可以在以后进行扩展。这非常有用,但如果需要使用rootScope值,nidhishkrishnan的解决方法确实有效。这是一个很好的攻击。好吧,你所说的是为了回答为什么我不能在html中使用$rootScope变量(没有$root。),但是当我使用Batarang插件查看$scope时,我可以清楚地看到$rootScope是所有其他变量的父$scope(包括指令中的独立作用域)。另外,angular官方文档中的定义是:“每个应用程序都有一个根作用域。所有其他作用域都是根作用域的后代作用域”()我将此标记为答案,因为它“解决”了我想要实现的目标(我不知道“$root”或者它可以这样使用)。然而,我认为马克·克莱恩的答案通常是最好的解决方案。太棒了!知道$rootScope在视图中变成$root非常有用,非常感谢!这是完美的,因为我需要做的是访问在rootScopeGood函数中定义的函数。它也在这里工作。你能解释一下为什么$root而不是$rootScope吗?我也注入了$rootScope,但它在函数调用时没有定义。+1非常感谢这一点,也感谢你为我指出了我试图实现的正确方向。我认为NidhishKrishnan's应该被接受为“答案”,因为我在评论中陈述了原因。常量用例+1,因为它们很少被使用。另外,关于不使用$rootScope的说明也是一个专业提示。
$new: function(isolate) {
  var ChildScope,
      child;

  if (isolate) {
    child = new Scope();
    child.$root = this.$root;
    child.$$asyncQueue = this.$$asyncQueue;
    child.$$postDigestQueue = this.$$postDigestQueue;
  } else {

    if (!this.$$childScopeClass) {
      this.$$childScopeClass = function() {
        // blah blah...
      };
      this.$$childScopeClass.prototype = this;
    }
    child = new this.$$childScopeClass();
  }