问题描述
我是新来的角,但真的很喜欢它的方法。我有我在哪里初始化变量, 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; DIV&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:
- 控制器实例
- prelinking
- 链接
- 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 $eval
s 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 $eval
uated 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 code>局部变量
- 在同一F,经过当地
directiveName
VAR被分配directive.name
道具的价值,我测试这对ngInit
静态字符串,这是标准化的名字角分配给NG-INIT
指令时,声明的节点 - 如果测试通过,我设置了
nodeHasInitData code>到
真正
。如果测试失败,不采取任何措施( - >nodeHasInitData code>仍然
未定义
在封闭) - 在
nodeLinkFn
F座,在这之前检查控制器在presence的如果
块节点(在上面的列表步骤1),我在nodeHasInitData code>的值(我能做到这增加了测试,因为
nodeLinkFn
被内部定义的applyDirectivesToNode
) - 如果测试通过,我调用
范围。$的eval(attrs.ngInit)
,这是什么$ P $砰砰F中的原生 NG-INIT 指令一样。无论范围
和ATTRS
是nodeLinkFn
本机参数,可以使它们是可用的。如果测试失败,什么都不做 - 这样,我搬到步骤2中的初始化一个新的台阶0,则执行相应的控制器的code之前哺养内埃尔范围
- in the
applyDirectivesToNode
f block I declare a non-initializednodeHasInitData
local var - in the same f, after the local
directiveName
var is assigned thedirective.name
prop value, I test it against the"ngInit"
static string, which is the normalized name Angular assigns to theng-init
directive when it is declared on the node - if the test passes, I set the
nodeHasInitData
totrue
. nothing is done if the test fails (->nodeHasInitData
remainsundefined
in the closure) - in the
nodeLinkFn
f block, before theif
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 ofnodeHasInitData
(I can do that becausenodeLinkFn
is defined insideapplyDirectivesToNode
) - if the test passes, I invoke
scope.$eval(attrs.ngInit)
, which is what the prelink f of the nativeng-init
directive does. bothscope
andattrs
are native params ofnodeLinkFn
, 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控制器:控制器的范围奇怪的行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!