Angular JS custom指令 - 属性绑定到字符串或范围变量

时间:2015-04-19 19:33:16

标签: angularjs angularjs-directive angularjs-scope

是否可以在创建自定义指令时使某个属性可以是字符串或双向绑定到范围内的某个属性?

所以,例如,如果我在我的指令声明中有这个:

$scope: {
    position: '=?'
}

然后在我的链接功能或控制器中提醒它:

$alert($scope.position);

如果我实际将它绑定到父作用域上的某些内容,它会起作用,但是如果我只是放入一个字符串,我会得到未定义,除非我在双引号内使用单引号。 E.g。

<my-directive position="'right'"></my-directive>

这样它将表达式计算为字符串,但它似乎很难看。我宁愿能够使用position =&#34;对&#34;当我想给属性一个字符串,或者使用position =&#34; {{scopeVariable}}&#34;当我想将它绑定到双向绑定到父控制器中的某些东西时。

我错了使用&#34; =?&#34;作为隔离范围绑定?有一个更好的方法吗?或者我应该习惯在双引号内使用单引号?

2 个答案:

答案 0 :(得分:2)

@=语法的差异可能会让人感到困惑。但这是因为后者使用$parse来转换表达式。前者使用$interpolate,它接受​​表达式风格的字符串并使用$ parse转换它。因此=的属性始终是一个表达式,而Angular在那里不需要{{ }}(否则将position="{{'right'}}"。并且@并不仅限于单个表达式或静态字符串(我不确定该手册是否明确提到过这一点)。

这种行为深埋在$ compile中,你无法在指令中覆盖它,$ parse会因为在任何事情之前表达无效而抛出错误。

要解决此问题,您需要在控制器或链接中重新实现= binding。我们所要做的就是$parse针对$ scope的表达式。$ parent,建立正确的观察者并在$ destroy上删除它。

答案 1 :(得分:1)

根据Angular文档,

=表示双向绑定 - 这意味着您必须使用引号。 如果要传递字符串,则应使用文本绑定:

$scope: {
    position: '@'
}

并且你可以传递像

这样的变量
<my-directive position="right"></my-directive>

<my-directive position="{{right}}"></my-directive>

但请记住,这是单向绑定。

如果您真的需要'混合'解决方案,有时是文本绑定,有时是双向绑定,您可以手动实现绑定

{
    scope: {}
    link: function(scope,element,attr){
        attr['position'] // the value of html attribute, use it directly or evaluate in parent scope
        scope.$parent.$eval(attr['position']); //evaluate variable 'right' in parent scope
    }
}