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

238

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

Нур Рони
источник
1
См. Также stackoverflow.com/questions/14050195/…
Марк Райкок

Ответы:

375

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

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

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

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

cliff.meyers
источник
1
Спасибо за выноску, я обновил свой ответ правильными URL-адресами.
cliff.meyers
43
Немного стыдно за то, что ответы с самыми высокими оценками ссылаются на видео за платой, когда, вероятно, существует масса бесплатного контента, содержащего ту же информацию.
BenCr
Есть много видео, которые предоставляются бесплатно
egghead
7
минус один за платный контент.
Арель Сапир
109

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

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

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

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

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

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

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

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

введите описание изображения здесь

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

@просто передает свойство из 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на be =, вы обнаружите, что можете изменить значение 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: ....

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

Радость
источник
По умолчанию директивы используют общую область видимости. Если директива имеет «scope: true», то она использует унаследованную область, в которой дочерний элемент может видеть родительские свойства, но родительский не может видеть дочерние внутренние свойства.
YuMei
1
AngularJS - изолированные области видимости - @ vs = vs & ---------- Короткие примеры с объяснениями доступны по ссылке ниже: codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
Prashanth
24

Не моя скрипка, но 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:'&'
        }        
JGM
источник
17

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

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

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

Timothy.Li
источник
5
важным предупреждением для @ является не только односторонняя, но и
встречная
@Shawson: Так как связать однонаправленную строку (например, int или bool)?
ИЛИ Mapper
Если на это настроено ваше сердце, вы можете взять значение @ и привести к int / bool? В противном случае я бы просто использовал = или <
Shawson
7

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>
Prashanth
источник
5

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

Есть хороший пост в блоге, который объясняет это по этому адресу: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes

Питер Никси
источник