Я внимательно прочитал документацию AngularJS по этой теме, а затем возился с директивой. Вот скрипка .
И вот некоторые соответствующие фрагменты:
Из HTML :
<pane bi-title="title" title="{{title}}">{{text}}</pane>
Из директивы панели:
scope: { biTitle: '=', title: '@', bar: '=' },
Есть несколько вещей, которые я не понимаю:
- Почему я должен использовать
"{{title}}"
с'@'
и"title"
с'='
? - Могу ли я также получить доступ к родительской области напрямую, не украшая свой элемент атрибутом?
- Документация гласит: «Часто желательно передавать данные из изолированной области через выражение и в родительскую область» , но, похоже, это работает и с двунаправленной привязкой. Почему маршрут выражения был бы лучше?
Я нашел другую скрипку, которая также показывает решение для выражения: http://jsfiddle.net/maxisam/QrCXh/
=
, используется в области действия директивы для включения двухстороннего связывания и@
не обновляет модель, а только обновляет значения области действия Директивы.Ответы:
@ связывает локальное / директивное свойство области видимости с оцененным значением атрибута DOM . Если вы используете
title=title1
илиtitle="title1"
, значение атрибута DOM "title" - это просто строкаtitle1
. Если вы используетеtitle="{{title}}"
, значение атрибута DOM "title" является интерполированным значением{{title}}
, следовательно, строка будет тем, какое свойство родительской области "title" в настоящее время установлено. Поскольку значения атрибута всегда являются строками, вы всегда получите строковое значение для этого свойства в области действия директивы при использовании @ .= связывает локальную / директивную область видимости с родительской областью видимости . Таким образом, с = вы используете имя свойства родительской модели / области действия в качестве значения атрибута DOM. Вы не можете использовать
{{}}
s с = .С @ вы можете делать такие вещи, как
title="{{title}} and then some"
- {{title}} интерполируется, затем строка «и их некоторые» объединяется с ним. Последняя конкатенированная строка - это то, что получает свойство области видимости local / directive. (Вы не можете сделать это с = , только @ .)С @ вам нужно использовать,
attr.$observe('title', function(value) { ... })
если вам нужно использовать значение в вашей функции ссылки (ing). Например,if(scope.title == "...")
не будет работать так, как вы ожидаете. Обратите внимание, что это означает, что вы можете получить доступ к этому атрибуту только асинхронно . Вам не нужно использовать $ наблюдаем (), если вы используете только значение в шаблоне. Например,template: '<div>{{title}}</div>'
.С = , вам не нужно использовать $ наблюдение.
Да, но только если вы не используете изолирующую область. Удалить эту строку из вашей директивы
scope: { ... }
и тогда ваша директива не создаст новую область. Он будет использовать родительскую область. Затем вы можете получить доступ ко всем свойствам родительской области напрямую.
Да, двунаправленная привязка позволяет локальной / директивной области и родительской области совместно использовать данные. «Привязка выражений» позволяет директиве вызывать выражение (или функцию), определенную атрибутом DOM, и вы также можете передавать данные в качестве аргументов в выражение или функцию. Итак, если вам не нужно обмениваться данными с родителем - вы просто хотите вызвать функцию, определенную в родительской области - вы можете использовать синтаксис & .
Смотрите также
источник
@
('at') копирует значение 'ATtribute'.=
(«равно») эквивалентно тому, что ключ равен вашему выражению. По крайней мере, так я их сдерживаю.foo="{{1+1}}"
- потому что здесь нам не нужно двустороннее связывание данных. Пункт, который я попытался сделать в комментарии выше, заключается в том, что мы должны использовать = только тогда, когда директива нуждается в двустороннем связывании данных. Используйте @ или & в противном случае.Есть много хороших ответов здесь, но я хотел бы предложить свою точку зрения о различиях между
@
,=
и&
что связывание оказалось полезным для меня.Все три привязки являются способами передачи данных из вашей родительской области в изолированную область вашей директивы через атрибуты элемента:
Я считаю, что легче запомнить эти различия, ссылаясь на привязки области видимости в более коротком описании:
@
Привязка строки атрибута=
Двухстороннее связывание моделей&
Привязка метода обратного вызоваСимволы также проясняют, что представляет переменная области видимости внутри реализации вашей директивы:
@
строка=
модель&
методВ порядке полезности (для меня в любом случае):
источник
"&"
поддерживает аргументы (или, скорее, местные) в форме:,callback({foo: "some value"})
которые затем могут быть использованы<my-dir callback="doSomething(foo)">
. В противном случае, хороший ответcallback(argument)
. Который до сих пор не такой, как онcallback
сам.Эти
=
средства двунаправленного связывания, так что ссылки на переменную в родительской области. Это означает, что когда вы изменяете переменную в директиве, она будет изменяться и в родительской области видимости.@
означает, что переменная будет скопирована (клонирована) в директиву.Насколько я знаю,
<pane bi-title="{{title}}" title="{{title}}">{{text}}</pane>
тоже должно работать.bi-title
получит значение родительской переменной области видимости, которое можно изменить в директиве.Если вам нужно изменить несколько переменных в родительской области, вы можете выполнить функцию в родительской области из директивы (или передать данные через службу).
источник
Если вы хотите увидеть больше, как это работает, на живом примере. http://jsfiddle.net/juanmendez/k6chmnch/
источник
@
получить как строку=
2 способа привязки&
Это ведет себя немного по-другому, потому что область действия получает функцию, которая возвращает переданный объект . Я предполагаю, что это было необходимо, чтобы заставить это работать. Скрипка должна прояснить это.Эта скрипка должна продемонстрировать, как они работают . Обратите особое внимание на функции видимости
get...
в названии, чтобы лучше понять, что я имею в виду&
источник
В директиву можно добавить три области действия:
Директива и ее родительский (контроллер / директива, в которой она находится) контекст одинаковы. Поэтому любые изменения, внесенные в переменные области видимости внутри директивы, также отражаются в родительском контроллере. Вам не нужно указывать это, так как это по умолчанию.
Здесь, если вы измените переменные области действия внутри директивы, она не будет отражаться в родительской области, но если вы измените свойство переменной области, которое отражается в родительской области, так как вы фактически изменили переменную области родительского элемента ,
Пример,
Это происходит, когда вы создаете плагины, так как это делает директиву общей, так как она может быть помещена в любой HTML и не затрагивается родительской областью.
Теперь, если вы не хотите никакого взаимодействия с родительской областью, то вы можете просто указать область как пустой объект. подобно,
По большей части это не так, поскольку нам нужно некоторое взаимодействие с родительской областью, поэтому мы хотим, чтобы некоторые значения / изменения были пройдены. По этой причине мы используем:
@ означает, что изменения в области действия контроллера будут отражены в области действия директивы, но если вы измените значение в области действия директивы, переменная области действия контроллера не будет затронута.
@ всегда ожидает, что сопоставленный атрибут будет выражением. Это очень важно; потому что для того, чтобы префикс «@» работал, нам нужно обернуть значение атрибута внутри {{}}.
= является двунаправленным, поэтому, если вы измените переменную в области действия директивы, это также повлияет на переменную области контроллера
& используется для привязки метода контекста контроллера, так что при необходимости мы можем вызвать его из директивы
Преимущество здесь в том, что имя переменной не обязательно должно совпадать в области видимости контроллера и области действия директивы.
Например, область действия директивы имеет переменную «dirVar», которая синхронизируется с переменной «contVar» области контроллера. Это дает большую мощность и обобщение директиве, поскольку один контроллер может синхронизироваться с переменной v1, в то время как другой контроллер, использующий ту же директиву, может запрашивать синхронизацию dirVar с переменной v2.
Ниже приведен пример использования:
Директива и контроллер:
И HTML (обратите внимание на разницу для @ и =):
Вот ссылка на блог, который описывает это красиво.
источник
Просто мы можем использовать: -
@ : - для строковых значений для односторонней привязки данных. с одной стороны, привязка данных, вы можете только передать значение области в директиву
= : - для значения объекта для двухсторонней привязки данных. При двухстороннем связывании данных вы можете изменить значение области действия как в директиве, так и в html.
& : - для методов и функций.
РЕДАКТИРОВАТЬ
В нашем определении Компонента для Angular версии 1.5 и выше
есть четыре различных типа привязок:
=
Двусторонняя привязка данных : - если мы изменим значение, оно автоматически обновится<
односторонняя привязка : - когда мы просто хотим прочитать параметр из родительской области, а не обновлять его.@
это для строковых параметров&
это для обратных вызовов в случае, если ваш компонент должен вывести что-то в родительскую область видимостиисточник
Я создал небольшой HTML-файл, содержащий код Angular, демонстрирующий различия между ними:
источник
= Путь 2-полосная привязки , который позволяет вам иметь живые изменения внутри вашей директивы. Когда кто-то изменяет эту переменную вне директивы, у вас будут эти измененные данные внутри вашей директивы, но @ way не является двухсторонней привязкой . Это работает как текст . Вы связываете один раз, и у вас будет только его значение.
Чтобы сделать это более понятным, вы можете использовать эту замечательную статью:
Область Директив AngularJS '@' и '='
источник
Этот вопрос уже забит до смерти, но я все равно поделюсь этим на случай, если кто-то еще будет бороться с ужасным беспорядком, который охватывает AngularJS. Это будет охватывать
=
,<
,@
,&
и::
. Полное описание можно найти здесь .=
устанавливает двухстороннее связывание. Изменение свойства в родительском элементе приведет к изменению дочернего элемента, и наоборот.<
устанавливает одностороннюю привязку, родитель к ребенку. Изменение свойства в родительском элементе приведет к изменению дочернего, но изменение дочернего свойства не повлияет на родительское свойство.@
присваивает дочернему свойству строковое значение атрибута тега. Если атрибут содержит выражение , дочернее свойство обновляется всякий раз, когда выражение оценивается в другую строку. Например:Здесь
description
свойство в дочерней области будет текущим значением выражения"The movie title is {{$ctrl.movie.title}}"
, гдеmovie
находится объект в родительской области.&
это немного сложно, и на самом деле, кажется, нет веской причины когда-либо использовать его. Это позволяет оценивать выражение в родительской области, заменяя параметры переменными из дочерней области. Пример ( plunk ):Учитывая
parentVar=10
, выражениеparentFoo({myVar:5, myOtherVar:'xyz'})
будет оцениваться5 + 10 + 'xyz'
и компонент будет отображаться как:Когда бы вы хотели использовать этот замысловатый функционал?
&
часто используется людьми для передачи в дочернюю область функции обратного вызова в родительской области. В действительности, однако, тот же эффект может быть достигнут с помощью «<» для передачи функции, которая является более простой и позволяет избежать неудобного синтаксиса фигурных скобок для передачи параметров ({myVar:5, myOtherVar:'xyz'}
). Рассматривать:Обратный звонок с использованием
&
:Обратный звонок с использованием
<
:Обратите внимание, что объекты (и массивы) передаются по ссылке на дочернюю область, а не копируются. Это означает, что даже если это односторонняя привязка, вы работаете с одним и тем же объектом как в родительской, так и в дочерней области.
Чтобы увидеть разные префиксы в действии, откройте этот план .
Одноразовая привязка (инициализация) с использованием::
[Официальные документы] В более
поздних версиях AngularJS появилась возможность иметь одноразовую привязку, когда свойство дочерней области обновляется только один раз. Это повышает производительность, устраняя необходимость следить за родительским свойством. Синтаксис отличается от выше; чтобы объявить одноразовую привязку, вы добавляете
::
перед выражением в теге компонента :Это будет распространять значение
tagline
в дочернюю область без установления односторонней или двусторонней привязки. Примечание : еслиtagline
изначальноundefined
в родительской области видимости, angular будет наблюдать за ней до тех пор, пока она не изменится, а затем выполнить одноразовое обновление соответствующего свойства в дочерней области.Резюме
В таблице ниже показано, как работают префиксы в зависимости от того, является ли свойство объектом, массивом, строкой и т. Д.
источник
@ local свойство scope используется для доступа к строковым значениям, которые определены вне директивы.
= В случаях, когда вам необходимо создать двустороннюю привязку между внешней областью действия и изолированной областью директивы, вы можете использовать символ =.
Свойство & local scope позволяет потребителю директивы передавать функцию, которую директива может вызвать.
Пожалуйста, проверьте ссылку ниже, которая дает вам четкое понимание с примерами. Я нашел это действительно очень полезным, поэтому подумал поделиться им.
http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope
источник
Даже если область является локальной, как в вашем примере, вы можете получить доступ к родительской области через свойство
$parent
. Предположим в приведенном ниже коде, которыйtitle
определен в родительской области видимости. Вы можете получить доступ к заголовку как$parent.title
:Однако в большинстве случаев тот же эффект лучше получить с помощью атрибутов.
Пример, где я нашел нотацию «&», которая используется «для передачи данных из изолированной области через выражение и в родительскую область», полезная (и двусторонняя привязка данных не может быть использована) была в директиве для рендеринга специальной структуры данных внутри ng-повторения.
Одной из частей рендеринга была кнопка удаления, и здесь было полезно прикрепить функцию удаления из внешней области с помощью &. Внутри директивы рендера это выглядит так
Двухсторонняя привязка данных, т.е.
data = "="
не может быть использована, поскольку функция удаления будет выполняться в каждом$digest
цикле, что не очень хорошо, поскольку запись немедленно удаляется и никогда не обрабатывается.источник
Я реализовал все возможные варианты в скрипке.
Здесь рассматриваются все варианты:
https://jsfiddle.net/rishulmatta/v7xf2ujm
источник
главное отличие между ними просто
источник
@
и=
увидеть другие ответы.Один Гоча о TL; DR; получает выражение (а не только функцию, как в примерах в других ответах) от родителя и устанавливает его как функцию в директиве, которая вызывает выражение. И эта функция имеет возможность заменить любую переменную (даже имя функции) выражения, передавая объект с переменными.
&
&
объяснил
&
это ссылка на выражение, это означает , что если вы что - то передать , как<myDirective expr="x==y"></myDirective>
в директиве это
expr
будет функция, которая вызывает выражение, например:function expr(){return x == y}
.так в html директивы
<button ng-click="expr()"></button>
будет вызывать выражение. В js директивы просто$scope.expr()
вызовут выражение тоже.Выражение будет вызываться с помощью $ scope.x и $ scope.y родителя.
У вас есть возможность переопределить параметры!
Если вы установите их по вызову, например,
<button ng-click="expr({x:5})"></button>
тогда выражение будет вызываться с вашим параметром
x
и параметром родителяy
.Вы можете переопределить оба.
Теперь вы знаете, почему
<button ng-click="functionFromParent({x:5})"></button>
работает.Потому что это просто вызывает выражение родителя (например,
<myDirective functionFromParent="function1(x)"></myDirective>
) и заменяет возможные значения указанными вами параметрами, в этом случаеx
.это может быть:
<myDirective functionFromParent="function1(x) + 5"></myDirective>
или
<myDirective functionFromParent="function1(x) + z"></myDirective>
с ребенком вызова:
<button ng-click="functionFromParent({x:5, z: 4})"></button>
.или даже с заменой функции:
<button ng-click="functionFromParent({function1: myfn, x:5, z: 4})"></button>
.это просто выражение, не имеет значения, является ли оно функцией, множеством функций или просто сравнением. И вы можете заменить любую переменную этого выражения.
Примеры:
шаблон директивы и вызываемый код:
родительский определил $ scope.x, $ scope.y:
родительский шаблон:
<myDirective expr="x==y"></myDirective>
<button ng-click="expr()"></button>
звонки$scope.x==$scope.y
<button ng-click="expr({x: 5})"></button>
звонки5 == $scope.y
<button ng-click="expr({x:5, y:6})"></button>
звонки5 == 6
parent определил $ scope.function1, $ scope.x, $ scope.y:
родительский шаблон:
<myDirective expr="function1(x) + y"></myDirective>
<button ng-click="expr()"></button>
звонки$scope.function1($scope.x) + $scope.y
<button ng-click="expr({x: 5})"></button>
звонки$scope.function1(5) + $scope.y
<button ng-click="expr({x:5, y:6})"></button>
звонки$scope.function1(5) + 6
директива $ scope.myFn как функция:
<button ng-click="expr({function1: myFn, x:5, y:6})"></button>
вызовы$scope.myFn(5) + 6
источник
Когда вы используете {{title}}, только родительское значение области будет передано в представление директивы и оценено. Это ограничено одним способом, означающим, что изменение не будет отражено в родительской области. Вы можете использовать '=', когда хотите отразить изменения, сделанные в дочерней директиве, в родительской области видимости. Это два пути.
Когда в директиве есть атрибут scope (scope: {}), вы больше не сможете напрямую обращаться к родительской области. Но, тем не менее, к нему можно получить доступ через scope. $ Parent и т. Д. Если вы удалите scope из директивы, к нему можно получить прямой доступ.
Это зависит от контекста. Если вы хотите вызвать выражение или функцию с данными, вы используете &, и если вы хотите обмениваться данными, вы можете использовать двунаправленный способ, используя '='
Вы можете найти различия между несколькими способами передачи данных в директиву по ссылке ниже:
AngularJS - изолированные области видимости - @ vs = vs &
http://www.codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
источник
@ Привязка строки атрибута (односторонняя) = двусторонняя привязка модели и привязка метода обратного вызова
источник
@ связывает локальное / директивное свойство области видимости с оцененным значением атрибута DOM. = связывает локальную / директивную область видимости с родительской областью видимости. & binding предназначен для передачи метода в область действия вашей директивы, чтобы его можно было вызывать в вашей директиве.
@ Привязка строки атрибута = двусторонняя привязка модели и привязка метода обратного вызова
источник