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

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

  1. = атр
  2. & атр
  3. @attr
  4. знак равно
  5. &
  6. @

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

2 ответа

Решение

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

Вот скрипка, которая должна помочь связать вещи вместе: 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);

Резюме

  1. @attr связывается с оцененным строковым значением соответствующего атрибута DOM.
  2. = attr связывается со свойством области видимости соответствующего атрибута DOM.
  3. & attr связывает с областью действия соответствующего атрибута DOM.
  4. @
  5. знак равно
  6. &

Мы используем 4, 5 и 6, если имя целевого атрибута DOM совпадает с именем proproty изолированной области видимости. Вот рабочая скрипка следующего примера.

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: '&'
        }
    };
});
Другие вопросы по тегам