【问题标题】:new scope that inherits from parent within angular directives在角度指令中从父级继承的新范围
【发布时间】:2013-04-06 21:29:37
【问题描述】:

假设我这样做:

sAngular.app.directive('dostuff', ['$compile', function($compile){
  return   {
    restrict : 'C',
    scope: {
      someVar : '='
    },
    link : function(scope, element, attrs){  
      element.click(function(){
           //do stuff
        scope.someVar = 'somethingelse';
        var dropdownOutput = template();
        var compiledOutput = $compile(dropdownOutput)(scope);
        scope.$apply();
     });
    }    
  }
}]);

我怎样才能让这个指令的范围从父范围继承一个变量,但仍然让它成为一个“隔离”范围

例如来自角度文档:

= 或 =attr - 在本地范围属性和通过值定义的名称的父范围属性之间设置双向绑定 attr 属性。如果未指定 attr 名称,则属性 假定名称与本地名称相同。范围的给定和小部件定义:{ localModel:'=myAttr' },然后小部件范围属性 localModel 将 在父作用域上反映 parentModel 的值。任何更改 parentModel 将反映在 localModel 和任何更改 localModel 将反映在 parentModel 中。

但是,在这种情况下,由于“localModel 中的任何更改都将反映在 parentModel 中”,如果我在该指令的范围内修改变量,然后在这种情况下执行 scope.apply(),它将相应地反映在父范围中,并且父模板将随着更改而更新

我也尝试将 "scope : true" 作为参数,但更改了范围,然后是 scope.$apply();也将传播到原始范围...

有没有办法让我可以从父范围复制一个范围,并且该范围内的变量仍然有更改不会传播到父范围?

【问题讨论】:

  • 不是 100% 清楚你想要什么......哪里有提供情况概述的演示?真的不清楚compiledOutput在做什么
  • @pillarOfLight 如果您不想将隔离作用域属性更改传播到父作用域,请使用@ 而不是=。抱歉更正了
  • @rajkamal,使用 & 会将作用域变量转换为函数,而不是让作用域变量从父作用域变量继承
  • @rajkamal,使用 @ 也不起作用......这应该引用 dom 属性元素,并且该值将始终是字符串而不是范围变量是什么(请参阅docs.angularjs.org/guide/directive scope部分)
  • 你试过在指令中使用 scope.$parent.variableName 吗?

标签: javascript angularjs angularjs-directive angularjs-scope


【解决方案1】:

我怎样才能让这个指令的范围从父范围继承一个变量,但仍然让它成为一个“隔离”范围

在这里使用“继承”这个词有点令人困惑。隔离范围不(典型地)从其父范围继承。 Angular 确实在隔离作用域上放置了 $parent 属性,因此您可以通过这种方式访问​​父作用域属性,但最佳实践是不要使用 $parent。如果您想要一个隔离范围,将父范围属性值传递到该隔离范围的唯一方法是使用=@&。这三个实际上都可以工作(甚至 '&' 也可以用于通过表达式传递属性值 - for the curious)。

在您的隔离范围内(或者如果您使用scope: true),您可以创建新属性。这些新属性不会传播回父级。因此,如果您想更改传递给指令的属性值,只需将其复制到指令范围内的某个新属性即可。

这是一个使用“单向字符串”语法@ 的示例。要获取父范围属性的(插值)值(作为字符串),请在 HTML 中使用 {{}}:

<div class="dostuff" some-var="{{interpolateThisParentScopePropertyPlease}}">

sAngular.app.directive('dostuff', ['$compile', function($compile){
  return   {
    restrict : 'C',
    scope: { someVar : '@' },
    link : function(scope, element, attrs){  
      element.click(function(){
        scope.myLocalDirectiveProperty = scope.someVar;
        scope.someOtherDirectiveProperty = 'somethingelse';
        var dropdownOutput = template();
        var compiledOutput = $compile(dropdownOutput)(scope);
        scope.$apply();
     });
    }

如果要将对象传递给指令,请使用 '=' 语法,然后使用 angular.copy() 在指令内制作对象的副本。


根据评论请求:

<div class="dostuff" some-obj="parentScopeObj">

sAngular.app.directive('dostuff', ['$compile', function($compile){
  return   {
    restrict : 'C',
    scope: { someObj : '=' },
    link : function(scope, element, attrs){  
      element.click(function(){
        scope.myLocalDirectiveObjProperty = angular.copy(scope.someObj);
        ...
        scope.$apply();
     });
    }

【讨论】:

  • 谢谢回复,你能给我一个传递对象的'='语法的例子,因为这是我感兴趣的
  • 如果你想使用与父作用域相同的变量名怎么办?有办法吗?如果我制作 some-obj parent-scope-obj 然后在指令中修改 scope.parentScopeObj 会影响父作用域的 parentScopeObj 吗?
  • 看看这是否回答了您的问题:您在 HTML 中使用的属性名称(例如,parent-scope-obj)与父范围属性名称无关。例如,假设父作用域属性是prop1,并且您将它作为&lt;div class="dostuff" parent-scope-obj="prop1"...&gt; 传递给指令。在指令中,您可以随意命名传递的属性,例如dirProp1,使用以下语法:scope: { dirProp1: '=parentScopeObj' }。现在,指令作用域属性dirProp1 和父作用域属性prop1 是“关联的”——改变其中一个总是会改变另一个。
猜你喜欢
  • 2013-10-07
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-13
  • 2014-05-20
  • 1970-01-01
相关资源
最近更新 更多