В чем разница между & vs @и = в angularJS

Я очень новичок в AngularJS. может ли кто-нибудь объяснить мне разницу между этими (&, @и =) при изолировании области с правильным примером.

Ответ 1

@ позволяет передать значение, определенное в атрибуте директивы, в область выделения директивы. Значение может быть простым строковым значением (myattr="hello"), или это может быть интерполированная строка AngularJS со встроенными выражениями (myattr="my_{{helloText}}"). Подумайте об этом как о "одностороннем" сообщении из родительской области в дочернюю директиву. У Джона Линдквиста есть серия коротких скринкастов, объясняющих каждый из них. Screencast on @находится здесь: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding

& позволяет директивам изолировать область действия для передачи значений в родительскую область для оценки в выражении, определенном в атрибуте. Обратите внимание, что атрибут директивы неявно является выражением и не использует синтаксис двойного фигурного скобки. Это сложнее объяснить в тексте. Screencast on и находится здесь: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding

= устанавливает двухстороннее выражение привязки между областью выделения директивы и родительской областью. Изменения в области дочерних объектов распространяются на родителя и наоборот. Подумайте = как сочетание @и &. Screencast on = находится здесь: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding

И, наконец, вот скринкаст, который показывает все три, используемые вместе в одном представлении: https://egghead.io/lessons/angularjs-isolate-scope-review

Ответ 2

Я хотел бы объяснить концепции с точки зрения наследования прототипа JavaScript. Надеюсь, поможет понять.

Существует три параметра для определения области действия директивы:

  • scope: false: Angular по умолчанию. Область действия директивы - это именно ее родительская область (parentScope).
  • scope: true: Angular создает область действия для этой директивы. Объем прототипически наследуется от parentScope.
  • scope: {...}: изолированная область видимости объясняется ниже.

Задание scope: {...} определяет isolatedScope. isolatedScope не наследует свойства от parentScope, хотя isolatedScope.$parent === parentScope. Он определяется через:

app.directive("myDirective", function() {
    return {
        scope: {
            ... // defining scope means that 'no inheritance from parent'.
        },
    }
})

isolatedScope не имеет прямого доступа к parentScope. Но иногда директива должна связываться с parentScope. Они обмениваются данными через @, = и &. Тема об использовании символов @, = и & говорит о сценариях с использованием isolatedScope.

Обычно он используется для некоторых общих компонентов, разделяемых разными страницами, например Modals. Изолированная область предотвращает загрязнение глобальной области и позволяет легко делиться между страницами.

Вот основная директива: http://jsfiddle.net/7t984sf9/5/. Изображение для иллюстрации:

enter image description here

@: односторонняя привязка

@ просто передает свойство от parentScope до isolatedScope. Он называется one-way binding, что означает, что вы не можете изменить значение свойств parentScope. Если вы знакомы с наследованием JavaScript, вы можете легко понять эти два сценария:

  • Если свойство привязки является примитивным типом, например interpolatedProp в примере: вы можете изменить interpolatedProp, но parentProp1 не будет изменен. Однако, если вы измените значение parentProp1, interpolatedProp будет перезаписано новым значением (когда Angular $digest).

  • Если свойство привязки представляет собой некоторый объект, например parentObj: поскольку переданный в isolatedScope является ссылкой, изменение значения вызывает эту ошибку:

    TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}

=: двусторонняя привязка

= называется two-way binding, что означает, что любая модификация в childScope также обновит значение в parentScope и наоборот. Это правило работает как для примитивов, так и для объектов. Если вы измените тип привязки parentObj на =, вы обнаружите, что можете изменить значение parentObj.x. Типичным примером является ngModel.

&: привязка функции

& позволяет директиве вызвать некоторую функцию parentScope и передать какое-то значение из директивы. Например, проверьте JSFiddle: и в области директивы.

Определите шаблон с кликабелем в директиве типа:

<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">

И используйте директиву как:

<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>

Переменная valueFromDirective передается из директивы в родительский контроллер через {valueFromDirective: ....

Ссылка: Понимание областей

Ответ 3

Не моя скрипка, но http://jsfiddle.net/maxisam/QrCXh/ показывает разницу. Ключ:

           scope:{
            /* NOTE: Normally I would set my attributes and bindings
            to be the same name but I wanted to delineate between 
            parent and isolated scope. */                
            isolatedAttributeFoo:'@attributeFoo',
            isolatedBindingFoo:'=bindingFoo',
            isolatedExpressionFoo:'&'
        }        

Ответ 4

Мне понадобилось много времени, чтобы действительно разобраться с этим. Ключом для меня было понимание того, что "@" - это материал, который вы хотите оценить in situ и переданный в директиву как константа, где "=" фактически передает сам объект.

Там хорошая запись в блоге, которая объясняет это следующим образом: http://blog.ramses.io/technical/[email protected]&-and-=-when-declaring-directives-using-isolate-scopes

Ответ 5

@: односторонняя привязка

=: двусторонняя привязка

&: привязка функции

Ответ 6

AngularJS - изолированные области - @vs = vs &


Краткие примеры с пояснениями доступны по ссылке:

http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs

@- односторонняя привязка

В директиве:

scope : { nameValue : "@name" }

В поле зрения:

<my-widget name="{{nameFromParentScope}}"></my-widget>

= - двусторонняя привязка

В директиве:

scope : { nameValue : "=name" },
link : function(scope) {
  scope.name = "Changing the value here will get reflected in parent scope value";
}

В поле зрения:

<my-widget name="{{nameFromParentScope}}"></my-widget>

& - вызов функции

В директиве:

scope : { nameChange : "&" }
link : function(scope) {
  scope.nameChange({newName:"NameFromIsolaltedScope"});
}

В поле зрения:

<my-widget nameChange="onNameChange(newName)"></my-widget>