【问题标题】:Correct usage of & binding in directives在指令中正确使用 & 绑定
【发布时间】:2015-03-11 03:57:13
【问题描述】:

我在answersgenerated some discussion 中提出了这个问题,我想弄清楚我是否偏离了基础,或者是否有一种“更有角度”的方式来实现我的目标。

当我编写一个将使用隔离作用域的指令时,出现的问题总是 =、& 或 @。

通常,人们总是认为 & 是一种将函数传递给指令的方式。 documentation 将其描述为:

一种在上下文中执行表达式的方法 父范围。如果未指定属性名称,则属性名称 假定与本地名称相同。范围的给定和小部件定义:{ localFn:'&myAttr' },则隔离范围属性 localFn 将指向 count = count + value 表达式的函数包装器。经常 最好通过表达式从隔离范围传递数据 到父范围,这可以通过传递本地地图来完成 变量名称和值放入表达式包装器 fn。例如, 如果表达式是增量(数量),那么我们可以指定数量 通过将 localFn 调用为 localFn({amount: 22}) 来获取值。

我用它来传递函数相当多,但我也用它来传递一个返回非字符串的表达式,并且我不希望我的指令能够修改父范围。换句话说,我将其用作:

一种在父作用域的上下文中执行表达式的方法

所以如果我不需要双向绑定,并且表达式不是字符串,我会这样做:

.directive('displayObject', function() {

    scope: {
        value: '&=displayObject'
    },
    template: '<div ng-repeat="(k, v) in value()">{{k}}: {{v}}</div>',
    replace: true,
    ...
});

指令的用法是:

<div displayObject="someScopePropertyOrExpression"></div>

= 在这里并不理想,因为我不需要双向绑定。我不希望我的指令修改父范围中的值,也不希望手表需要维护它。

@ 并不理想,因为它会插入属性,因此 value 始终是字符串。

::someScopePropertyOrExpression 不起作用,因为我希望指令模板在 someScopePropertyOrExpression 发生变化时反映它的变化。

在每次讨论中,总是提到

ng-repeat="(key, value) in value()"

设置一个手表-问题是=和模板一起设置了两个-一个是完全没有必要的。

当我多次提出这种模式时,它被称为“hack”,或误用 &,甚至“丑陋”。

我不认为是这些,但如果是,那么我的具体问题是替代方案是什么?

【问题讨论】:

    标签: angularjs angularjs-directive


    【解决方案1】:

    我在discussion here 中进行了大量搜索以证明您错了,但我认为您是对的 - 这是设置单向(从父级到隔离范围)绑定到实际的唯一方法型号。

    在这方面"&amp;" 优于"=",因为正如您所指出的,"=" 设置了对父范围的监视,而"&amp;" 没有。

    有一件事 - plunker 1 - (我终于设法发现)暗示它是一个 hack 是它与 Angular 的一次性绑定 foo="::name" 不兼容:

    "=" 将遵守一次性绑定(它在父节点上设置监视并在下一个摘要之前将其删除),而 "&amp;" 不会:

    <input ng-model="name">
    <div two-way="::name">
    <div one-way="::name">
    

    另一件事 - plunker 2 - 是 "&amp;" 允许传递局部变量,它们可能会影响外部变量:

    <input ng-model="name">
    <div one-way="name">
    

    但是在指令中,如果你做了类似"{{oneWay({name: 'fooo'})}}" 的操作,它会导致它显示"fooo",而不是从外部范围获取name 的值。 是的,这有点像朝自己的脚开枪,但它确实暗示这种用法可能稍微超出了它的初衷。

    【讨论】:

    • 感谢您回答 NewDev。如果您想要一次绑定,则 ='::name' 是要走的路。但就我而言,我没有。我想维护 parent->directive 绑定(当表达式的值发生变化时,指令会更新)。如果您只需要一次绑定,那么我同意,从可读性的角度来看, ='::name' 会比 the equivalent & 解决方案更好。另外,请记住 :: 是 1.3+ 中的新功能。
    • 关于你的第二个问题,我认为通过当地人的能力实际上更像是一种“黑客”。看this plunk。使用“baz”,如果指令的使用者不知道指令用于传递数据的本地名称,则会出现意外结果。 baz2其实是我比较喜欢的,因为它让指令界面更干净(界面的细节不再埋没在模板里)。
    • @JoeEnzminger,首先,我的观点是指令用户(而不是作者)有权决定进行一次性绑定,这在任何地方都可以使用,除非使用此实现.所以,在这种情况下,“你”不是你——作者,所以你不能声称你只是想维护“父级->指令绑定”
    • @JoeEnzminger,实际上,baz2(如果它是一个真正的函数调用)对我来说似乎非常错误。它将您的控制器功能(应该独立存在)与视图想要的功能相结合。换句话说,如果我想做:baz="doSomething(item, prop, '123')",那么它就将如何将 View 与 ViewModel 连接起来,包括如何处理从指令返回的数据 (prop) 给 View 的作者留下了灵活性.但既不在这里也不在那里。第 2 点,其实是指令作者的呼唤,所以这就是我所说的“打自己的脚”
    • 另外,第二次......如果内置指令(如 ng-clickng-keypress 返回局部变量 $event
    猜你喜欢
    • 2012-12-14
    • 2019-02-26
    • 1970-01-01
    • 2015-09-08
    • 2016-11-04
    • 1970-01-01
    • 1970-01-01
    • 2021-02-25
    • 2015-11-10
    相关资源
    最近更新 更多