Відповіді:
@
дозволяє передати значення, визначене атрибутом директиви, в область ізоляції директиви. Значення може бути простим значенням рядка ( myattr="hello"
) або може бути інтерпольованим рядком AngularJS із вбудованими виразами ( myattr="my_{{helloText}}"
). Розгляньте це як "одностороннє" спілкування з материнської сфери в директиву щодо дитини. Джон Ліндквіст має ряд коротких скріншотів, що пояснюють кожне з них. Екранна трансляція на @ є тут: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding
&
дозволяє області ізоляції директиви передавати значення в батьківську область для оцінки в виразі, визначеному в атрибуті. Зауважимо, що атрибут директиви є неявним виразом і не використовує синтаксис подвійного фігурного дужки вираза. Це важче пояснити в тексті. Екранна трансляція & тут: 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
Я хотів би пояснити поняття з точки зору успадкування прототипу JavaScript. Сподіваємось, допоможемо зрозуміти.
Існує три варіанти визначення сфери дії директиви:
scope: false
: Кутове значення за замовчуванням. Область застосування директиви - це саме її головна область застосування ( 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
буде замінено новим значенням (при кутовому переривці $).
Якщо властивість прив'язки є деяким об'єктом, як-от 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: ...
.
Довідка: Розуміння сфер застосування
Не моя скрипка, але 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:'&'
}
@ : одностороння прив'язка
= : двостороння зв'язування
& : зв'язування функції
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>
Мені знадобилось пекло довго, щоб справді зрозуміти це. Ключовим моїм завданням було розуміння того, що "@" - це те, що ви хочете оцінити in situ і передане в директиву як константа, де "=" фактично передає сам об'єкт.
Там в блог хороший пост , який пояснює це це по адресою: http://blog.ramses.io/technical/AngularJS-the-difference-between-@-&-and-=-when-declaring-directives-using-isolate-scopes