В чем разница между & 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/. Изображение для иллюстрации:
@
: односторонняя привязка
@
просто передает свойство от 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>