AngularJS: Различия между = & @в области действия?

Создание изолировать область внутри директивы позволяет сопоставить внешнюю область с внутренней областью. Мы видели шесть разных способов отображения на attrbutes:

  • = атр
  • & атр
  • @attr
  • =
  • &
  • @

Что делает каждый из этих вариантов отображения области видимости?

Ответ 1

Это может ввести в заблуждение, но, надеюсь, простой пример это прояснит. Во-первых, отделите привязки модели от поведения.

Вот скрипка, которая должна помочь связать вещи вместе: http://jsfiddle.net/jeremylikness/3pvte/

И объяснил... если ваша директива выглядит так:

<my-directive target="foo"/> 

Тогда у вас есть эти возможности для области видимости:

{ target : '=' } 

Это привяжет scope.target(директиву) к $scope.foo(внешняя область). Это связано с тем, что = для двусторонней привязки, и когда вы ничего не указываете, оно автоматически сопоставляет имя во внутренней области с именем атрибута директивы. Изменения в scope.target будут обновлены $scope.foo.

{ bar : '=target' } 

Это привяжет scope.bar к $scope.foo. Это связано с тем, что мы снова указываем двустороннюю привязку, но сообщаем директиве, что то, что находится в атрибуте "target", должно отображаться во внутренней области как "bar". Изменения в scope.bar будут обновлять $scope.foo.

{ target : '@' } 

Это установит scope.target на "foo", потому что @означает "воспринимать это буквально". Изменения в scope.target не будут распространяться вне вашей директивы.

{ bar : '@target' } 

Это установит scope.bar в "foo", потому что @принимает значение из целевого атрибута. Изменения в scope.bar не будут распространяться вне вашей директивы.

Теперь позвольте говорить о поведении. Пусть ваш внешний охват имеет следующее:

$scope.foo = function(parm1, parm2) { console.log(parm1 + ": " + parm2); } 

Существует несколько способов доступа к этому. Если ваш HTML:

<my-directive target='foo'>

Тогда

{ target : '=' } 

Позволяет вам вызвать scope.target(1,2) из ​​вашей директивы.

То же самое,

{ bar : '=target' }

Позволяет вам вызвать scope.bar(1,2) из ​​вашей директивы.

Более распространенный способ - установить это как поведение. Технически амперсанд оценивает выражение в контексте родителя. Это важно. Поэтому я мог бы:

<my-directive target="a+b" />

И если родительская область имеет $scope.a = 1 и $scope.b = 2, то по моей директиве:

{ target: '&' } 

Я могу вызвать scope.target(), и результат будет равен 3. Это важно - привязка отображается как функция во внутренней области, но директива может связываться с выражением.

Более общий способ сделать это:

<my-directive target="foo(val1,val2)"> 

Затем вы можете использовать:

{ target: '&' }

И вызов из директивы:

scope.target({val1: 1, val2: 2}); 

Это принимает объект, который вы передали, сопоставляет свойства с параметрами в оцениваемом выражении, а затем вызывает поведение, в этом случае вызывается $scope.foo(1,2);

Вы также можете сделать это:

<my-directive target="foo(1, val)"/>

Это блокирует первый параметр для литерала 1 и директивы:

{ bar: '&target' }

Тогда:

scope.bar(5) 

Что бы назвать $scope.foo(1,5);

Ответ 2

Резюме

  • @attr привязывается к соответствующему атрибуту DOM, оцениваемому string.
  • = attr связывается с подходящей областью атрибута DOM свойство.
  • & attr связывается с подходящей областью свойств DOM .
  • @
  • =
  • &

Мы используем 4, 5 и 6, если имя атрибута целевого DOM соответствует имени свойства области изоляции. Ниже приведен пример работы fiddle.

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>

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: '&'
        }
    };
});