AngularJS:指令范围内=&@之间的差异?

Sha*_*tin 107 angularjs angularjs-directive angularjs-scope isolated-scope

在指令中创建隔离范围允许我们将外部范围映射到内部范围.我们已经看到了六种不同的方式来映射到attrbutes:

  1. =属性
  2. &ATTR
  3. @attr
  4. =
  5. &
  6. @

每个范围映射选项的作用是什么?

Jer*_*ess 198

这可能令人困惑,但希望一个简单的例子可以澄清它.首先,让我们将模型绑定与行为分开.

这是一个小提琴应该有助于把事情联系在一起:http://jsfiddle.net/jeremylikness/3pvte/

并解释......如果您的指令如下所示:

<my-directive target="foo"/> 
Run Code Online (Sandbox Code Playgroud)

然后你有这些范围的可能性:

{ target : '=' } 
Run Code Online (Sandbox Code Playgroud)

这会将scope.target(指令)绑定到$ scope.foo(外部作用域).这是因为=用于双向绑定,当您没有指定任何内容时,它会自动将内部作用域上的名称与指令上属性的名称相匹配.对scope.target的更改将更新$ scope.foo.

{ bar : '=target' } 
Run Code Online (Sandbox Code Playgroud)

这会将scope.bar绑定到$ scope.foo.这是因为我们再次指定双向绑定,但告诉指令属性"target"中的内容应该作为"bar"出现在内部作用域上.对scope.bar的更改将更新$ scope.foo.

{ target : '@' } 
Run Code Online (Sandbox Code Playgroud)

这会将scope.target设置为"foo",因为@表示"从字面上理解".对scope.target的更改不会在指令之外传播.

{ bar : '@target' } 
Run Code Online (Sandbox Code Playgroud)

这会将scope.bar设置为"foo",因为@从目标属性中获取它的值.对scope.bar的更改不会在指令之外传播.

现在让我们谈谈行为吧.让我们假设您的外部范围包含:

$scope.foo = function(parm1, parm2) { console.log(parm1 + ": " + parm2); } 
Run Code Online (Sandbox Code Playgroud)

有几种方法可以访问它.如果你的HTML是:

<my-directive target='foo'>
Run Code Online (Sandbox Code Playgroud)

然后

{ target : '=' } 
Run Code Online (Sandbox Code Playgroud)

允许您从指令中调用scope.target(1,2).

一样,

{ bar : '=target' }
Run Code Online (Sandbox Code Playgroud)

允许您从指令调用scope.bar(1,2).

更常见的方法是将此作为一种行为.从技术上讲,&符号在父语境中评估表达式.这很重要.所以我可以:

<my-directive target="a+b" />
Run Code Online (Sandbox Code Playgroud)

如果父作用域有$ scope.a = 1和$ scope.b = 2,那么在我的指令上:

{ target: '&' } 
Run Code Online (Sandbox Code Playgroud)

我可以调用scope.target(),结果将是3.这很重要 - 绑定作为函数公开给内部作用域,但指令可以绑定到表达式.

更常见的方法是:

<my-directive target="foo(val1,val2)"> 
Run Code Online (Sandbox Code Playgroud)

然后你可以使用:

{ target: '&' }
Run Code Online (Sandbox Code Playgroud)

并从指令调用:

scope.target({val1: 1, val2: 2}); 
Run Code Online (Sandbox Code Playgroud)

这将获取您传递的对象,将属性映射到计算表达式中的参数,然后调用行为,这种情况称为$ scope.foo(1,2);

你也可以这样做:

<my-directive target="foo(1, val)"/>
Run Code Online (Sandbox Code Playgroud)

这会将第一个参数锁定到文字1,并从指令中锁定:

{ bar: '&target' }
Run Code Online (Sandbox Code Playgroud)

然后:

scope.bar(5) 
Run Code Online (Sandbox Code Playgroud)

哪个会叫$ scope.foo(1,5);


Sha*_*tin 44

摘要

  1. @attr绑定到匹配的DOM属性的计算字符串值.
  2. = attr绑定到匹配的DOM属性的scope 属性.
  3. &attr绑定到匹配的DOM属性的范围函数.
  4. @
  5. =
  6. &

如果目标DOM属性的名称与隔离范围属性名称匹配,则使用4,5和6.这是以下示例的工作小提琴.

HTML

<div ng-app='isolate'>
     <h3>Outer Scope</h3>

    <input type="text" ng-model="myModel" />
    <p>msg: {{ msg }}</p>
     <h3>Inner Scope</h3>

    <div id="inner">
        <div my-directive at="{{ myModel }}" equals="myModel" ampersand="msg=msg+'click'"></div>
    </div>
</div>
Run Code Online (Sandbox Code Playgroud)

使用Javascript

angular.module('isolate', [])
    .directive('myDirective', function () {
    return {
        template:
            '<label>@attr</label><input value="{{ myAt }}" />' +
            '<label>@</label><input value="{{ at }}" />' +
            '<label>=attr</label><input ng-model="myEquals" />' +
            '<label>=</label><input ng-model="equals" />' +
            '<label>&attr</label><input type="button" ng-click="myAmpersand()" value="Btn" />' +
            '<label>&</label><input type="button" ng-click="ampersand()" value="Btn" />',
        scope: {
            myAt: '@at',
            myEquals: '=equals',
            myAmpersand: '&ampersand',
            at: '@',
            equals: '=',
            ampersand: '&'
        }
    };
});
Run Code Online (Sandbox Code Playgroud)