Использование символов '@', '&', '=' и '>' в привязке области действия пользовательской директивы: AngularJS


151

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

var mainApp = angular.module("mainApp", []);
mainApp.directive('modalView',function(){
  return{
     restrict:'E',
     scope:'@' OR scope:'&' OR scope:'=' OR scope:'>' OR scope:true
  }
});

Что именно мы делаем с прицелом здесь?

Я также не уверен, существует ли "scope: '>'" в официальной документации или нет. Это было использовано в моем проекте.

Edit-1

Использование "scope: '>'" было проблемой в моем проекте, и оно было исправлено.

Ответы:


116

В директиве AngularJS область позволяет вам получить доступ к данным в атрибутах элемента, к которому применяется директива.

Это лучше всего иллюстрируется на примере:

<div my-customer name="Customer XYZ"></div>

и определение директивы:

angular.module('myModule', [])
.directive('myCustomer', function() {
  return {
    restrict: 'E',
    scope: {
      customerName: '@name'
    },
    controllerAs: 'vm',
    bindToController: true,
    controller: ['$http', function($http) {
      var vm = this;

      vm.doStuff = function(pane) {
        console.log(vm.customerName);
      };
    }],
    link: function(scope, element, attrs) {
      console.log(scope.customerName);
    }
  };
});

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

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

someObject: '=' (двусторонняя привязка данных)

someString: '@'(передается напрямую или через интерполяцию с двойными фигурными скобками {{}})

someExpression: '&'(например hideDialog())

Эта информация присутствует на странице документации директивы AngularJS , хотя и несколько распространена по всей странице.

Символ >не является частью синтаксиса.

Однако <существует как часть привязок компонента AngularJS и означает одностороннюю привязку.


6
Как насчет @??
Гомер

9
Стоит отметить, что <он совместим не только с компонентами версии 1.5, но и с директивами. @Homer ?обозначает атрибут как необязательный .
Дженс Бодал

171

> нет в документации.

< для односторонней привязки.

@привязка для передачи строк. Эти строки поддерживают {{}}выражения для интерполированных значений.

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

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

Когда мы устанавливаем scope: true в директиве, Angular js создаст новую область для этой директивы. Это означает, что любые изменения, внесенные в область действия директивы, не будут отражены в родительском контроллере.


47

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

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

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

@ передать только строки


6
Нет смысла повторять один и тот же ответ, извините, не тот же ответ. Кажется, извлеченная информация из приведенных выше ответов.
MAC

19
иногда более короткий ответ имеет тенденцию быть более практичным!
Марвен Трабелси

не нужно добавлять ненужную информацию, если вы можете объяснить это в нескольких коротких строках :)
Marwen Trabelsi

1
Это было бы лучше в качестве редактирования, чтобы привести любой из вариантов с более высоким рейтингом.
N-съел

3

Когда мы создаем директиву customer, область действия директивы может быть в изолированной области, это означает, что директива не разделяет область с контроллером; и директива, и контроллер имеют свою область видимости. Однако данные могут быть переданы в область действия директивы тремя возможными способами.

  1. Данные могут передаваться в виде строки с использованием @строкового литерала, передаваемого строкового значения, односторонней привязки.
  2. Данные могут передаваться как объект с использованием =строкового литерала, проходного объекта, 2 способа привязки.
  3. Данные могут передаваться как функция &строкового литерала, вызывать внешнюю функцию, передавать данные из директивы в контроллер.

2

Документация AngularJS по директивам довольно хорошо написана для обозначения символов.

Чтобы быть ясно, вы не можете просто иметь

scope: '@'

в определении директивы. У вас должны быть свойства, к которым применяются эти привязки, например:

scope: {
    myProperty: '@'
}

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

Вот прямая цитата из вышеупомянутой ссылки, касающаяся значений scope:

Свойство scope может иметь значение true, объект или ложное значение:

  • falsy : для директивы не будет создаваться область действия. Директива будет использовать область видимости своего родителя.

  • true: Для элемента директивы будет создана новая дочерняя область, которая прототипически наследуется от ее родителя. Если несколько директив одного и того же элемента запрашивают новую область, создается только одна новая область. Новое правило области действия не применяется к корню шаблона, поскольку корень шаблона всегда получает новую область действия.

  • {...} (объектный хеш) : для элемента директивы создается новая «изолированная» область видимости. Область «изолировать» отличается от обычной области тем, что она не наследуется по прототипу от родительской области. Это полезно при создании повторно используемых компонентов, которые не должны случайно читать или изменять данные в родительской области.

Получено 2017-02-13 из https://code.angularjs.org/1.4.11/docs/api/ng/service/ $ compile # -scope-, лицензировано как CC-by-SA 3.0


0

У меня были проблемы с привязкой значения к любому из символов в AngularJS 1.6. Я не получил никакого значения, только undefined, хотя я сделал это точно так же, как другие привязки в том же файле, который работал.

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

Это не удается:

bindings: { import_nr: '='}

Это работает:

bindings: { importnr: '='}

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

Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.