本文介绍了NG-INIT + NG控制器:控制器的范围奇怪的行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我是新来的角,但真的很喜欢它的方法。我有我在哪里初始化变量, NG-INIT ℃的HTML文件; DIV> 元素,其中我还宣布与 NG-控制器指令控制器:

I'm new to Angular but really enjoying its approach. I have an HTML file where I am initializing a variable with ng-init in a <div> element, where I'm also declaring a controller with the ng-controller directive:

<div ng-controller="myCtrl" ng-init='foo="bar"'>

如果我的console.log 从控制器脚本 $范围对象,我可以看到<$ C $其他人之间的C>富属性中列出,但是当我尝试从同一个脚本访问它,它给了我未定义。我还使用<一个href=\"https://chrome.google.com/webstore/detail/angularjs-batarang/ighdmehidhipcmcojjgiloacoafjmpfk?hl=en\">Batarang它显示我模型&LT; D​​IV&GT; -scope还包括属性

If I console.log the $scope object from the controller script I can see the foo property listed among the others, but when I try to access it from the same script it gives me undefined. I'm also using Batarang and it shows me a model for the <div>-scope that also includes the foo property.

我从第二个答案Pass ?变量AngularJS控制器,最佳实践中,我可以通过移动我的 NG-INIT 指令到外&LT解决问题; DIV&GT ; ,但我想知道究竟怎么回事就在这里幕后。任何帮助非常AP preciated,先谢谢了。

I know from the second answer to Pass variables to AngularJS controller, best practice? that I can solve the problem by moving my ng-init directive into an outer <div>, but I would like to know what is really going on here behind the scenes. Any help greatly appreciated, thanks in advance.

指令中的的顺序DIV 元素并不重要。这个问题仍然存在,即使 NG-INIT 之前指定纳克控制器

The order of the directives in the div element does not matter. The problem is still there even if ng-init is specified before ng-controller

推荐答案

好吧,我想我想通了。

NG-INIT 外/内ELS的不同行为产生的原因角执行其编制阶段的方式。编译包括不同的步骤。在这种情况下,最相关的是:

the different behavior of ng-init in outer/inner els arises because of the way Angular executes its compiling phase. compiling consists of different steps. the most relevant in this case are:


  1. 控制器实例

  2. prelinking

  3. 链接

  4. postlinking

这是发生在这个顺序对每个れ基础上(即每个节点,控制器code,如果present,在任何$ P $砰砰,链接或postlink˚F之前执行)

that take place in this order on a per-DOMnode basis (i.e. for each node, the controller code, if present, is executed before any prelink, link, or postlink f)

NG-INIT 注册了一个 pre 连杆式F中的节点上它被指定的,这 $ EVAL S上的指令的内容(在我的例子中,F分配一个值道具)。这样,当执行用于在同一个节点控制器code时,丙还不存在,这是在与@阿隆的应答线

ng-init registers a pre-link f on the node it is specified in, which $evals the directive's content (in my example, the f assigns a value to the foo prop). so, when the controller code for the same node is executed, the prop does not exist yet, which is in line with @Aron's answer

在编译阶段,角横贯从根向下深度优先的基础上,这意味着父ELS正在他们的孩子之前编译DOM中。在外部EL把 NG-INIT 指令允许子节点的控制器继承外的范围。这说明了外报'黑客

in the compile phase, Angular traverses the DOM from the root down on a depth-first basis, which means that parent els are compiled before their children. putting the ng-init directive in an outer el allows the controller of the child node to inherit the outer's scope. this explains the 'outer el' hack

黑客@Aron点在支架注册一个观察者,这样一来,当道具终于 $ EVAL uated在$ p $砰砰阶段,回调F能够找到它。

the hack @Aron points to registers an observer on the prop, so that, when the prop is finally $evaluated in the prelink phase, the callback f can find it

我建议基于异步JS和角度的功能其他两个可能的黑客(见)。 1涉及使用的setTimeout JS天然F,而另一种是更'角'​​,度假村到 $ evalAsync

I suggest two other possible hacks based on asynchronous JS and Angular features (see this jsFiddle). one involves using setTimeout JS native f, whereas the other is more 'Angular' and resorts to $evalAsync

恕我直言,有一个在角的实施 NG-INIT 指令相对于声明的意图缺陷。我已经砍死角的code尝试多样化的实现。由此不难(2号线code的补充,甚至在可能删除 NG-INIT 指令本土code),当应用到$工作在上述的jsfiddle C $ C,但我没有测试它复杂的应用程序。对于那些有兴趣,这里是我在做什么(裁判是到v 1.2.0-RC2):

imho, there's a flaw in Angular's implementation of the ng-init directive with respect to the declared intent. I have hacked the Angular's code to experiment a diverse implementation. It is not difficult (2 lines of code added, even before possibly removing the ng-init directive native code), and works when applied to the code in the jsFiddle above, but I have not tested it on complex apps. For those interested, here is what I'm doing (refs are to v 1.2.0-rc2):


  • applyDirectivesToNode F座我宣布一个未初始化 nodeHasInitData 局部变量

  • 在同一F,经过当地 directiveName VAR被分配 directive.name 道具的价值,我测试这对ngInit静态字符串,这是标准化的名字角分配给 NG-INIT 指令时,声明的节点

  • 如果测试通过,我设置了 nodeHasInitData 真正。如果测试失败,不采取任何措施( - > nodeHasInitData 仍然未定义在封闭)

  • nodeLinkFn F座,在这之前检查控制器在presence的如果块节点(在上面的列表步骤1),我在 nodeHasInitData 的值(我能做到这增加了测试,因为 nodeLinkFn 被内部定义的 applyDirectivesToNode

  • 如果测试通过,我调用范围。$的eval(attrs.ngInit),这是什么$ P $砰砰F中的原生 NG-INIT 指令一样。无论范围 ATTRS nodeLinkFn 本机参数,可以使它们是可用的。如果测试失败,什么都不做

  • 这样,我搬到步骤2中的初始化一个新的台阶0,则执行相应的控制器的code之前哺养内埃尔范围

  • in the applyDirectivesToNode f block I declare a non-initialized nodeHasInitData local var
  • in the same f, after the local directiveName var is assigned the directive.name prop value, I test it against the "ngInit" static string, which is the normalized name Angular assigns to the ng-init directive when it is declared on the node
  • if the test passes, I set the nodeHasInitData to true. nothing is done if the test fails (-> nodeHasInitData remains undefined in the closure)
  • in the nodeLinkFn f block, before the if block that checks for the presence of controllers in the node (step 1 in the list above), I'm adding a test on the value of nodeHasInitData (I can do that because nodeLinkFn is defined inside applyDirectivesToNode)
  • if the test passes, I invoke scope.$eval(attrs.ngInit), which is what the prelink f of the native ng-init directive does. both scope and attrs are native params of nodeLinkFn, so they are available. nothing is done if the test fails
  • this way, I have moved the initialization from step 2 to a new step 0, which feeds the inner el scope before the corresponding controller's code is executed


 1.其实,我已经复制它,因为˚F由 NG-INIT 指令定义的$ P $砰砰仍然存在。这不是一个很大的,但是,我认为它可以通过改变/删除指令对象很容易地避免

要避免复制,它是安全的,黑客的说明目的如上所述,在<$来替换 ngInitDirective 角VAR的分配code C $ C> VAR ngInitDirective = valueFn({});

To avoid replication, it is safe, for the illustrative purposes of the hack described above, to replace the assignment code of the ngInitDirective Angular var with var ngInitDirective = valueFn({});

这篇关于NG-INIT + NG控制器:控制器的范围奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-24 19:10