В чем разница между '@' и '=' в области действия директивы в AngularJS?

1067

Я внимательно прочитал документацию AngularJS по этой теме, а затем возился с директивой. Вот скрипка .

И вот некоторые соответствующие фрагменты:

  • Из HTML :

    <pane bi-title="title" title="{{title}}">{{text}}</pane>
  • Из директивы панели:

    scope: { biTitle: '=', title: '@', bar: '=' },

Есть несколько вещей, которые я не понимаю:

  • Почему я должен использовать "{{title}}"с '@'и "title"с '='?
  • Могу ли я также получить доступ к родительской области напрямую, не украшая свой элемент атрибутом?
  • Документация гласит: «Часто желательно передавать данные из изолированной области через выражение и в родительскую область» , но, похоже, это работает и с двунаправленной привязкой. Почему маршрут выражения был бы лучше?

Я нашел другую скрипку, которая также показывает решение для выражения: http://jsfiddle.net/maxisam/QrCXh/

Iwein
источник
18
Честная оценка. Способность исследовать и находить ответы очень важна.
Джонатан
1
Простыми словами =, используется в области действия директивы для включения двухстороннего связывания и @не обновляет модель, а только обновляет значения области действия Директивы.
СТАЛЬ
@iwein, почему ваш скриптовый код на jsfiddle.net/maxisam/QrCXh не работает с googleapi - ajax.googleapis.com/ajax/libs/angularjs/1.4.8/angular.min.js ? Ваш код работает, только если я использую ваш cdn - code.angularjs.org/1.0.1/angular-1.0.1.js
MukulSharma
Я вижу много хороших ответов ниже, но может ли кто-нибудь дать указатель на официальную документацию, которая отвечает на этот вопрос?
Джон Хенкель

Ответы:

1151

Почему я должен использовать «{{title}}» с « @ » и «заголовок» с « = »?

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

Смотрите также

Марк Райкок
источник
1
Да, это действительно странное поведение, особенно если не использовать интерполяцию и просто пытаться передать строку. По-видимому, запрос на удаление действительно был объединен со сборками разработки и находится в сборках RC 1.1.5 и 1.2.0. Хорошо, что они исправили это очень не интуитивное поведение!
Ибрагим
50
Написание «@» или «=» намного понятнее, чем написание «eval-dom», «parent-scope» или любого другого читаемого человеком текста. Хорошее дизайнерское решение.
день
13
@('at') копирует значение 'ATtribute'. =(«равно») эквивалентно тому, что ключ равен вашему выражению. По крайней мере, так я их сдерживаю.
Matt DeKrey
1
Вы уверены, что = только для свойств родительской области? Кажется, работает любое выражение - не только свойства родительской области.
Джонатан Акино
4
@JonathanAquino, да, это работает, но @ было бы более уместным - с foo="{{1+1}}"- потому что здесь нам не нужно двустороннее связывание данных. Пункт, который я попытался сделать в комментарии выше, заключается в том, что мы должны использовать = только тогда, когда директива нуждается в двустороннем связывании данных. Используйте @ или & в противном случае.
Марк Райкок
542

Есть много хороших ответов здесь, но я хотел бы предложить свою точку зрения о различиях между @, =и &что связывание оказалось полезным для меня.

Все три привязки являются способами передачи данных из вашей родительской области в изолированную область вашей директивы через атрибуты элемента:

  1. @ привязка для передачи строк. Эти строки поддерживают {{}}выражения для интерполированных значений. Например: . Интерполированное выражение оценивается по родительской области действия директивы.

  2. = связывание для двустороннего связывания моделей. Модель в родительской области видимости связана с моделью в изолированной области действия директивы. Изменения в одной модели влияют на другую, и наоборот.

  3. & binding предназначен для передачи метода в область действия вашей директивы, чтобы его можно было вызывать в вашей директиве. Метод предварительно привязан к родительской области действия директивы и поддерживает аргументы. Например, если метод является hello (name) в родительской области, тогда для выполнения метода изнутри вашей директивы вы должны вызвать $ scope.hello ({name: 'world'})

Я считаю, что легче запомнить эти различия, ссылаясь на привязки области видимости в более коротком описании:

  • @ Привязка строки атрибута
  • = Двухстороннее связывание моделей
  • & Привязка метода обратного вызова

Символы также проясняют, что представляет переменная области видимости внутри реализации вашей директивы:

  • @ строка
  • = модель
  • & метод

В порядке полезности (для меня в любом случае):

  1. знак равно
  2. @
  3. &
pixelbits
источник
13
На самом деле, "&"поддерживает аргументы (или, скорее, местные) в форме:, callback({foo: "some value"})которые затем могут быть использованы <my-dir callback="doSomething(foo)">. В противном случае, хороший ответ
New Dev
11
Должен быть принят ответ. Вот краткая статья с той же информацией, но с добавленными примерами кода: umur.io/…
Кевин
4
& НЕ является «привязкой метода обратного вызова», это привязка углового выражения. Особенным, но не единственным примером является выражение callback(argument). Который до сих пор не такой, как он callbackсам.
Дмитрий Зайцев
14
Хотя мне нравилось, насколько решительным был ответ с более высоким рейтингом, я обнаружил, что он оказал более полезное влияние, и после прочтения этого я понял предыдущий ответ намного больше.
rbnzdave
1
Я согласен с приведенным выше комментарием, этот ответ является более четким, окончательным и полезным для вопроса. Это объясняет достаточно подробно, что вы можете пойти и использовать информацию.
user3125823
64

Эти =средства двунаправленного связывания, так что ссылки на переменную в родительской области. Это означает, что когда вы изменяете переменную в директиве, она будет изменяться и в родительской области видимости.

@ означает, что переменная будет скопирована (клонирована) в директиву.

Насколько я знаю, <pane bi-title="{{title}}" title="{{title}}">{{text}}</pane>тоже должно работать. bi-titleполучит значение родительской переменной области видимости, которое можно изменить в директиве.

Если вам нужно изменить несколько переменных в родительской области, вы можете выполнить функцию в родительской области из директивы (или передать данные через службу).

asgoth
источник
1
Да, та часть, которую я получаю, вижу скрипку в вопросе. Но как насчет неясных частей?
Iwein
4
дело в том, что {{}} не работает с =. = не оценивается, но строка принимается как имя свойства как есть. Спасибо за ответ!
iwein
1
Я не думаю, что = только для переменных в родительской области. Работает с любым выражением (например, 1 + 1).
Джонатан Акино
1
@JonathanAquino Вы правы, что он оценивает выражения. Имхо, это на самом деле странно, и я бы не стал так использовать. Именно такие хитрые трюки делают директивные рамки настолько сложными для меня, во-первых, для понимания.
Iwein
1
Я единственный, кто считает этот ответ неправильным! «=» означает «угловой», ожидает выражение javascript и будет выполнять двунаправленное отображение, если передана переменная области действия. Принимая во внимание, что @ означает угловое ожидание строки и все. На самом деле это правда, что если вы используете @ в сочетании с {{}}, вы клонируете значение переменной. Но это не определение @!
Люк Дюзан
39

Если вы хотите увидеть больше, как это работает, на живом примере. http://jsfiddle.net/juanmendez/k6chmnch/

var app = angular.module('app', []);
app.controller("myController", function ($scope) {
    $scope.title = "binding";
});
app.directive("jmFind", function () {
    return {
        replace: true,
        restrict: 'C',
        transclude: true,
        scope: {
            title1: "=",
            title2: "@"
        },
        template: "<div><p>{{title1}} {{title2}}</p></div>"
    };
});
Хуан Мендес
источник
2
Есть несколько примеров, связанных в вопросе и верхнем ответе. Что это добавляет?
iwein
10
@iwein, это добавляет ясности. Если бы я мог понять и усвоить полнофункциональные примеры, мне бы этот сайт не понадобился.
Тони Эннис
3
Хуан, может исправить твои опечатки? 'transclude' написано с ошибкой. еще лучше, удалите его (и все остальное, например, «заменить»), который не вносит непосредственного вклада в проблему, поэтому ваше решение будет еще проще и понятнее. +1 за пример.
Тони Эннис
Спасибо @AnikISlamAbhi за редактирование. Я хотел бы внести больший вклад, и я рад, что некоторые находят мои образцы полезными. Это основная цель.
Хуан Мендес
Неполный пример. В вашей демонстрации вы меняете только двунаправленное значение. Вы даже не пытаетесь изменить значение, которое имеет изолированную область. Таким образом, он не продемонстрировал должным образом, как работает контекст в директивах.
Sudarshan_SMD
38

@ получить как строку

  • Это не создает никаких привязок вообще. Вы просто получаете слово, которое вы передали в виде строки

= 2 способа привязки

  • Изменения, сделанные с контроллера, будут отражены в справочной информации, содержащейся в директиве, и наоборот

&Это ведет себя немного по-другому, потому что область действия получает функцию, которая возвращает переданный объект . Я предполагаю, что это было необходимо, чтобы заставить это работать. Скрипка должна прояснить это.

  • После вызова этой функции получения результирующий объект ведет себя следующим образом:
    • если функция была передана: то функция выполняется в закрытии родителя (контроллера) при вызове
    • если была передана не-функция : просто получите локальную копию объекта, который не имеет привязок


Эта скрипка должна продемонстрировать, как они работают . Обратите особое внимание на функции видимости get...в названии, чтобы лучше понять, что я имею в виду&

ГЕГ
источник
36

В директиву можно добавить три области действия:

  1. Родительская область : это наследование области по умолчанию.

Директива и ее родительский (контроллер / директива, в которой она находится) контекст одинаковы. Поэтому любые изменения, внесенные в переменные области видимости внутри директивы, также отражаются в родительском контроллере. Вам не нужно указывать это, так как это по умолчанию.

  1. Дочерняя область действия : директива создает дочернюю область, которая наследуется от родительской области, если вы задаете переменную области действия директивы как true.

Здесь, если вы измените переменные области действия внутри директивы, она не будет отражаться в родительской области, но если вы измените свойство переменной области, которое отражается в родительской области, так как вы фактически изменили переменную области родительского элемента ,

Пример,

app.directive("myDirective", function(){

    return {
        restrict: "EA",
        scope: true,
        link: function(element, scope, attrs){
            scope.somvar = "new value"; //doesnot reflect in the parent scope
            scope.someObj.someProp = "new value"; //reflects as someObj is of parent, we modified that but did not override.
        }
    };
});
  1. Изолированная область : используется, если вы хотите создать область, которая не наследуется от области контроллера.

Это происходит, когда вы создаете плагины, так как это делает директиву общей, так как она может быть помещена в любой HTML и не затрагивается родительской областью.

Теперь, если вы не хотите никакого взаимодействия с родительской областью, то вы можете просто указать область как пустой объект. подобно,

scope: {} //this does not interact with the parent scope in any way

По большей части это не так, поскольку нам нужно некоторое взаимодействие с родительской областью, поэтому мы хотим, чтобы некоторые значения / изменения были пройдены. По этой причине мы используем:

1. "@"   (  Text binding / one-way binding )
2. "="   ( Direct model binding / two-way binding )
3. "&"   ( Behaviour binding / Method binding  )

@ означает, что изменения в области действия контроллера будут отражены в области действия директивы, но если вы измените значение в области действия директивы, переменная области действия контроллера не будет затронута.

@ всегда ожидает, что сопоставленный атрибут будет выражением. Это очень важно; потому что для того, чтобы префикс «@» работал, нам нужно обернуть значение атрибута внутри {{}}.

= является двунаправленным, поэтому, если вы измените переменную в области действия директивы, это также повлияет на переменную области контроллера

& используется для привязки метода контекста контроллера, так что при необходимости мы можем вызвать его из директивы

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

Например, область действия директивы имеет переменную «dirVar», которая синхронизируется с переменной «contVar» области контроллера. Это дает большую мощность и обобщение директиве, поскольку один контроллер может синхронизироваться с переменной v1, в то время как другой контроллер, использующий ту же директиву, может запрашивать синхронизацию dirVar с переменной v2.

Ниже приведен пример использования:

Директива и контроллер:

 var app = angular.module("app", []);
 app.controller("MainCtrl", function( $scope ){
    $scope.name = "Harry";
    $scope.color = "#333333";
    $scope.reverseName = function(){
     $scope.name = $scope.name.split("").reverse().join("");
    };
    $scope.randomColor = function(){
        $scope.color = '#'+Math.floor(Math.random()*16777215).toString(16);
    };
});
app.directive("myDirective", function(){
    return {
        restrict: "EA",
        scope: {
            name: "@",
            color: "=",
            reverse: "&"
        },
        link: function(element, scope, attrs){
           //do something like
           $scope.reverse(); 
          //calling the controllers function
        }
    };
});

И HTML (обратите внимание на разницу для @ и =):

<div my-directive
  class="directive"
  name="{{name}}"
  reverse="reverseName()"
  color="color" >
</div>

Вот ссылка на блог, который описывает это красиво.

Kop4lyf
источник
& не является ни «привязкой поведения», ни «привязкой метода», это привязка углового выражения.
Дмитрий Зайцев
20

Просто мы можем использовать: -

  1. @ : - для строковых значений для односторонней привязки данных. с одной стороны, привязка данных, вы можете только передать значение области в директиву

  2. = : - для значения объекта для двухсторонней привязки данных. При двухстороннем связывании данных вы можете изменить значение области действия как в директиве, так и в html.

  3. & : - для методов и функций.

РЕДАКТИРОВАТЬ

В нашем определении Компонента для Angular версии 1.5 и выше
есть четыре различных типа привязок:

  1. = Двусторонняя привязка данных : - если мы изменим значение, оно автоматически обновится
  2. < односторонняя привязка : - когда мы просто хотим прочитать параметр из родительской области, а не обновлять его.

  3. @это для строковых параметров

  4. &это для обратных вызовов в случае, если ваш компонент должен вывести что-то в родительскую область видимости

одж кулкарни
источник
13

Я создал небольшой HTML-файл, содержащий код Angular, демонстрирующий различия между ними:

<!DOCTYPE html>
<html>
  <head>
    <title>Angular</title>
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
  </head>
  <body ng-app="myApp">
    <div ng-controller="myCtrl as VM">
      <a my-dir
        attr1="VM.sayHi('Juan')" <!-- scope: "=" -->
        attr2="VM.sayHi('Juan')" <!-- scope: "@" -->
        attr3="VM.sayHi('Juan')" <!-- scope: "&" -->
      ></a>
    </div>
    <script>
    angular.module("myApp", [])
    .controller("myCtrl", [function(){
      var vm = this;
      vm.sayHi = function(name){
        return ("Hey there, " + name);
      }
    }])
    .directive("myDir", [function(){
      return {
        scope: {
          attr1: "=",
          attr2: "@",
          attr3: "&"
        },
        link: function(scope){
          console.log(scope.attr1);   // =, logs "Hey there, Juan"
          console.log(scope.attr2);   // @, logs "VM.sayHi('Juan')"
          console.log(scope.attr3);   // &, logs "function (a){return h(c,a)}"
          console.log(scope.attr3()); // &, logs "Hey there, Juan"
        }
      }
    }]);
    </script>
  </body>
</html>
RobertAKARobin
источник
6

= Путь 2-полосная привязки , который позволяет вам иметь живые изменения внутри вашей директивы. Когда кто-то изменяет эту переменную вне директивы, у вас будут эти измененные данные внутри вашей директивы, но @ way не является двухсторонней привязкой . Это работает как текст . Вы связываете один раз, и у вас будет только его значение.

Чтобы сделать это более понятным, вы можете использовать эту замечательную статью:

Область Директив AngularJS '@' и '='

Хазарапет Тунанян
источник
6

Этот вопрос уже забит до смерти, но я все равно поделюсь этим на случай, если кто-то еще будет бороться с ужасным беспорядком, который охватывает AngularJS. Это будет охватывать =, <, @, &и ::. Полное описание можно найти здесь .


=устанавливает двухстороннее связывание. Изменение свойства в родительском элементе приведет к изменению дочернего элемента, и наоборот.


<устанавливает одностороннюю привязку, родитель к ребенку. Изменение свойства в родительском элементе приведет к изменению дочернего, но изменение дочернего свойства не повлияет на родительское свойство.


@присваивает дочернему свойству строковое значение атрибута тега. Если атрибут содержит выражение , дочернее свойство обновляется всякий раз, когда выражение оценивается в другую строку. Например:

<child-component description="The movie title is {{$ctrl.movie.title}}" />
bindings: {
    description: '@', 
}

Здесь descriptionсвойство в дочерней области будет текущим значением выражения "The movie title is {{$ctrl.movie.title}}", где movieнаходится объект в родительской области.


&это немного сложно, и на самом деле, кажется, нет веской причины когда-либо использовать его. Это позволяет оценивать выражение в родительской области, заменяя параметры переменными из дочерней области. Пример ( plunk ):

<child-component 
  foo = "myVar + $ctrl.parentVar + myOtherVar"
</child-component>
angular.module('heroApp').component('childComponent', {
  template: "<div>{{  $ctrl.parentFoo({myVar:5, myOtherVar:'xyz'})  }}</div>",
  bindings: {
    parentFoo: '&foo'
  }
});

Учитывая parentVar=10, выражение parentFoo({myVar:5, myOtherVar:'xyz'})будет оцениваться 5 + 10 + 'xyz'и компонент будет отображаться как:

<div>15xyz</div>

Когда бы вы хотели использовать этот замысловатый функционал? &часто используется людьми для передачи в дочернюю область функции обратного вызова в родительской области. В действительности, однако, тот же эффект может быть достигнут с помощью «<» для передачи функции, которая является более простой и позволяет избежать неудобного синтаксиса фигурных скобок для передачи параметров ( {myVar:5, myOtherVar:'xyz'}). Рассматривать:

Обратный звонок с использованием &:

<child-component parent-foo="$ctrl.foo(bar)"/>
angular.module('heroApp').component('childComponent', {
  template: '<button ng-click="$ctrl.parentFoo({bar:'xyz'})">Call foo in parent</button>',
  bindings: {
    parentFoo: '&'
  }
});

Обратный звонок с использованием <:

<child-component parent-foo="$ctrl.foo"/>
angular.module('heroApp').component('childComponent', {
  template: '<button ng-click="$ctrl.parentFoo('xyz')">Call foo in parent</button>',
  bindings: {
    parentFoo: '<'
  }
});

Обратите внимание, что объекты (и массивы) передаются по ссылке на дочернюю область, а не копируются. Это означает, что даже если это односторонняя привязка, вы работаете с одним и тем же объектом как в родительской, так и в дочерней области.


Чтобы увидеть разные префиксы в действии, откройте этот план .

Одноразовая привязка (инициализация) с использованием ::

[Официальные документы] В более
поздних версиях AngularJS появилась возможность иметь одноразовую привязку, когда свойство дочерней области обновляется только один раз. Это повышает производительность, устраняя необходимость следить за родительским свойством. Синтаксис отличается от выше; чтобы объявить одноразовую привязку, вы добавляете ::перед выражением в теге компонента :

<child-component 
  tagline = "::$ctrl.tagline">
</child-component>

Это будет распространять значение taglineв дочернюю область без установления односторонней или двусторонней привязки. Примечание : если taglineизначально undefinedв родительской области видимости, angular будет наблюдать за ней до тех пор, пока она не изменится, а затем выполнить одноразовое обновление соответствующего свойства в дочерней области.

Резюме

В таблице ниже показано, как работают префиксы в зависимости от того, является ли свойство объектом, массивом, строкой и т. Д.

Как работают различные привязки изоляторов

Михаил Костира
источник
4

@ local свойство scope используется для доступа к строковым значениям, которые определены вне директивы.

= В случаях, когда вам необходимо создать двустороннюю привязку между внешней областью действия и изолированной областью директивы, вы можете использовать символ =.

Свойство & local scope позволяет потребителю директивы передавать функцию, которую директива может вызвать.

Пожалуйста, проверьте ссылку ниже, которая дает вам четкое понимание с примерами. Я нашел это действительно очень полезным, поэтому подумал поделиться им.

http://weblogs.asp.net/dwahlin/creating-custom-angularjs-directives-part-2-isolate-scope

Рафаэль
источник
3

Даже если область является локальной, как в вашем примере, вы можете получить доступ к родительской области через свойство $parent. Предположим в приведенном ниже коде, который titleопределен в родительской области видимости. Вы можете получить доступ к заголовку как $parent.title:

link : function(scope) { console.log(scope.$parent.title) },
template : "the parent has the title {{$parent.title}}"

Однако в большинстве случаев тот же эффект лучше получить с помощью атрибутов.

Пример, где я нашел нотацию «&», которая используется «для передачи данных из изолированной области через выражение и в родительскую область», полезная (и двусторонняя привязка данных не может быть использована) была в директиве для рендеринга специальной структуры данных внутри ng-повторения.

<render data = "record" deleteFunction = "dataList.splice($index,1)" ng-repeat = "record in dataList" > </render>

Одной из частей рендеринга была кнопка удаления, и здесь было полезно прикрепить функцию удаления из внешней области с помощью &. Внутри директивы рендера это выглядит так

scope : { data = "=", deleteFunction = "&"},
template : "... <button ng-click = "deleteFunction()"></button>"

Двухсторонняя привязка данных, т.е. data = "="не может быть использована, поскольку функция удаления будет выполняться в каждом $digestцикле, что не очень хорошо, поскольку запись немедленно удаляется и никогда не обрабатывается.

user3750988
источник
3

Я реализовал все возможные варианты в скрипке.

Здесь рассматриваются все варианты:

scope:{
    name:'&'
},

scope:{
    name:'='
},

scope:{
    name:'@'
},

scope:{

},

scope:true,

https://jsfiddle.net/rishulmatta/v7xf2ujm

Ришул Матта
источник
3

главное отличие между ними просто

@ Attribute string binding
= Two-way model binding
& Callback method binding
Ашиш Камбл
источник
1

@и =увидеть другие ответы.

Один Гоча о 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

ya_dimon
источник
0

Почему я должен использовать «{{title}}» с «@» и «заголовок» с «=»?

Когда вы используете {{title}}, только родительское значение области будет передано в представление директивы и оценено. Это ограничено одним способом, означающим, что изменение не будет отражено в родительской области. Вы можете использовать '=', когда хотите отразить изменения, сделанные в дочерней директиве, в родительской области видимости. Это два пути.

Могу ли я также получить доступ к родительской области напрямую, не украшая свой элемент атрибутом?

Когда в директиве есть атрибут scope (scope: {}), вы больше не сможете напрямую обращаться к родительской области. Но, тем не менее, к нему можно получить доступ через scope. $ Parent и т. Д. Если вы удалите scope из директивы, к нему можно получить прямой доступ.

Документация гласит: «Часто желательно передавать данные из изолированной области с помощью выражения и в родительскую область», но, похоже, это работает и с двунаправленной привязкой. Почему маршрут выражения будет лучше?

Это зависит от контекста. Если вы хотите вызвать выражение или функцию с данными, вы используете &, и если вы хотите обмениваться данными, вы можете использовать двунаправленный способ, используя '='

Вы можете найти различия между несколькими способами передачи данных в директиву по ссылке ниже:

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

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

Prashanth
источник
0

@ Привязка строки атрибута (односторонняя) = двусторонняя привязка модели и привязка метода обратного вызова

Джатин Патель
источник
0

@ связывает локальное / директивное свойство области видимости с оцененным значением атрибута DOM. = связывает локальную / директивную область видимости с родительской областью видимости. & binding предназначен для передачи метода в область действия вашей директивы, чтобы его можно было вызывать в вашей директиве.

@ Привязка строки атрибута = двусторонняя привязка модели и привязка метода обратного вызова

Ашиш Камбл
источник