如何从一个自定义指令*在AngularJS自己的范围之内*父访问范围? [英] How to access parent scope from within a custom directive *with own scope* in AngularJS?

查看:188
本文介绍了如何从一个自定义指令*在AngularJS自己的范围之内*父访问范围?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在寻找一个指令中访问父范围的任何方式。范围任意组合,transclude,要求,从上面传递变量(或范围本身),等等。我完全愿意拼命工作,但我想避免一些完全哈克或难以维护。例如,我知道我可以通过采取 $范围从$ P $砰砰参数并遍历它现在就做 $兄弟范围来寻找概念父。

我真正想要的是能够 $观看父作用域的前pression。如果我能做到这一点,那么我可以完成我想要做在这里:
<一href=\"http://stackoverflow.com/questions/17863732/angularjs-how-to-render-a-partial-with-variables\">AngularJS - 如何使局部使用变量

重要提示是该指令必须是可重复使用相同的父范围之内。因此,默认行为(范围:FALSE)不为我工作。我需要每个指令的情况下个人的范围,然后我需要 $观看生活在父作用域的变量。

一个code样品是值得1000的话,那么:

  app.directive('watchingMyParentScope',函数(){
    返回{
        要求:/ *? * /
        范围: /* ? * /
        transclude:/ *? * /
        控制器:/ *? * /
        编译:功能(EL,ATTR,反式){
            //我可以从transclusion功能不知何故$父?
            返回{
                pre:函数($ S,$ E,$ A,parentControl){
                    //我可以从父控制器的$父?
                    //通过设置这个。$范围= $范围从控制器内?                    //我可以从目前的$范围$父?                    //我可以传递$父范围,作为属性,并定义
                    //它作为该指令的范围定义的一部分吗?                    //有什么不我了解指令的工作原理和
                    //如何其范围涉及到他们的父母?
                },
                岗位:函数($ S,$ E,$ A,parentControl){
                    //已我的情况被postLink被调用的时候改善?
                }
            }
        }
    };
});


解决方案

请参阅What范围是原型/原型继承的细微差别AngularJS?

要总结:一路指令访问其父( $父)范围取决于范围的指令创建的类型:


  1. 默认情况下(范围:假) - 该指令不创建一个新的范围,所以这里没有继承。该指令的范围是同一范围内的父/容器。在链接功能,使用第一个参数(一般范围)。


  2. 范围:真正的 - 指令创建一个新的子作用域中典型从父继承的范围。可用于指示范围(因为原型继承的),这些父范围定义的属性。只是要小心写入原始scope属性的 - 这将在指令范围内创建一个新的属性(隐藏/阴影的同名父作用域属性)


  3. 范围:{...} - 指令创建一个新的分离/隔离范围。它不中典型继承父范围。您仍然可以访问使用 $父父范围,但是这通常不建议。相反,你应该指定父作用域属性(和/或功能)的指令,通过在使用该指令在相同的元素附加属性的需求,使用 = @ &放大器; 标记


  4. transclude:真正的 - 指令创建一个新的transcluded子范围,其中中典型从父继承的范围。如果该指令还创建了一个隔离范围,transcluded和分离范围是兄弟姐妹。每个范围的 $父属性引用相同的父作用域结果的角V1.3更新:如果该指令还创建了一个分离范围中,transcluded范围现在是分离范围的孩子。该transcluded隔离范围不再是兄弟姐妹。在 $父的transcluded范围的属性现在引用分离范围。


上面的链接了所有4种类型的实例和图片。

您无法访问范围,该指令的编译功能(这里提到:<一href=\"https://github.com/angular/angular.js/wiki/Understanding-Directives\">https://github.com/angular/angular.js/wiki/Understanding-Directives).您可以访问该指令的范围中的链接功能。

观赏:

有关1.以上2:通常你指定哪个父母财产的指令通过属性需要,那么$看着它:

 &LT; D​​IV我-DIR ATTR1 =为prop1&GT;&LT; / DIV&GT;

  $范围手表(attrs.attr1,函数(){...})。

如果你正在看一个对象的属性,你需要使用$解析:

 &LT; D​​IV我-DIR attR2位=obj.prop2&GT;&LT; / DIV&GT;

  VAR模型= $解析(attrs.attr2);
范围$腕表(型号,功能(){...})。

有关上述3(分离范围),看名字你给使用指令属性 @ = 注释:

 &LT; D​​IV我-DIR attr3 ={{prop3}}attr4 =obj.prop4&GT;&LT; / DIV&GT;

 范围:{
  localName3:@ attr3',
  attr4:'='//这里,使用相同的名称属性
},
链接:功能(范围,元素,ATTRS){
   。范围手表$('localName3',函数(){...});
   范围$腕表('attr4',函数(){...})。

I'm looking for any manner of accessing the "parent" scope within a directive. Any combination of scope, transclude, require, passing in variables (or the scope itself) from above, etc. I'm totally willing to bend over backwards, but I want to avoid something totally hacky or unmaintainable. For example, I know I could do it right now by taking the $scope from the preLink parameters and iterating over it's $sibling scopes to find the conceptual "parent".

What I really want is to be able to $watch an expression in the parent scope. If I can do that, then I can accomplish what I'm trying to do over here: AngularJS - How to render a partial with variables?

An important note is that the directive must be re-usable within the same parent scope. Therefore the default behavior (scope: false) doesn't work for me. I need an individual scope per instance of the directive, and then I need to $watch a variable that lives in the parent scope.

A code sample is worth 1000 words, so:

app.directive('watchingMyParentScope', function() {
    return {
        require: /* ? */,
        scope: /* ? */,
        transclude: /* ? */,
        controller: /* ? */,
        compile: function(el,attr,trans) {
            // Can I get the $parent from the transclusion function somehow?
            return {
                pre: function($s, $e, $a, parentControl) {
                    // Can I get the $parent from the parent controller?
                    // By setting this.$scope = $scope from within that controller?

                    // Can I get the $parent from the current $scope?

                    // Can I pass the $parent scope in as an attribute and define
                    // it as part of this directive's scope definition?

                    // What don't I understand about how directives work and
                    // how their scope is related to their parent?
                },
                post: function($s, $e, $a, parentControl) {
                    // Has my situation improved by the time the postLink is called?
                }
            }
        }
    };
});

解决方案

See What are the nuances of scope prototypal / prototypical inheritance in AngularJS?

To summarize: the way a directive accesses its parent ($parent) scope depends on the type of scope the directive creates:

  1. default (scope: false) - the directive does not create a new scope, so there is no inheritance here. The directive's scope is the same scope as the parent/container. In the link function, use the first parameter (typically scope).

  2. scope: true - the directive creates a new child scope that prototypically inherits from the parent scope. Properties that are defined on the parent scope are available to the directive scope (because of prototypal inheritance). Just beware of writing to a primitive scope property -- that will create a new property on the directive scope (that hides/shadows the parent scope property of the same name).

  3. scope: { ... } - the directive creates a new isolate/isolated scope. It does not prototypically inherit the parent scope. You can still access the parent scope using $parent, but this is not normally recommended. Instead, you should specify which parent scope properties (and/or function) the directive needs via additional attributes on the same element where the directive is used, using the =, @, and & notation.

  4. transclude: true - the directive creates a new "transcluded" child scope, which prototypically inherits from the parent scope. If the directive also creates an isolate scope, the transcluded and the isolate scopes are siblings. The $parent property of each scope references the same parent scope.
    Angular v1.3 update: If the directive also creates an isolate scope, the transcluded scope is now a child of the isolate scope. The transcluded and isolate scopes are no longer siblings. The $parent property of the transcluded scope now references the isolate scope.

The above link has examples and pictures of all 4 types.

You cannot access the scope in the directive's compile function (as mentioned here: https://github.com/angular/angular.js/wiki/Understanding-Directives). You can access the directive's scope in the link function.

Watching:

For 1. and 2. above: normally you specify which parent property the directive needs via an attribute, then $watch it:

<div my-dir attr1="prop1"></div>

scope.$watch(attrs.attr1, function() { ... });

If you are watching an object property, you'll need to use $parse:

<div my-dir attr2="obj.prop2"></div>

var model = $parse(attrs.attr2);
scope.$watch(model, function() { ... });

For 3. above (isolate scope), watch the name you give the directive property using the @ or = notation:

<div my-dir attr3="{{prop3}}" attr4="obj.prop4"></div>

scope: {
  localName3: '@attr3',
  attr4:      '='  // here, using the same name as the attribute
},
link: function(scope, element, attrs) {
   scope.$watch('localName3', function() { ... });
   scope.$watch('attr4',      function() { ... });

这篇关于如何从一个自定义指令*在AngularJS自己的范围之内*父访问范围?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆