Uso dos símbolos '@', '&', '=' e '>' na ligação do escopo da diretiva personalizada: AngularJS

151

Eu li muito sobre o uso desses símbolos na implementação de diretivas personalizadas no AngularJS, mas o conceito ainda não está claro para mim. Quero dizer, o que significa se eu usar um dos valores de escopo na diretiva personalizada?

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

O que exatamente estamos fazendo com o escopo aqui?

Também não tenho certeza se "scope: '>'" existe ou não na documentação oficial. Tem sido usado no meu projeto.

Edit-1

O uso de "scope: '>'" foi um problema no meu projeto e foi corrigido.

MAC
fonte

Respostas:

116

Em uma diretiva AngularJS, o escopo permite acessar os dados nos atributos do elemento ao qual a diretiva é aplicada.

Isso é ilustrado melhor com um exemplo:

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

e a definição de diretiva:

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);
    }
  };
});

Quando o scope propriedade é usada, a diretiva está no modo "escopo isolado", o que significa que ela não pode acessar diretamente o escopo do controlador pai.

Em termos muito simples, o significado dos símbolos de ligação é:

someObject: '=' (ligação de dados bidirecional)

someString: '@'(passado diretamente ou por interpolação com notação de chaves duplas {{}})

someExpression: '&' (por exemplo: hideDialog() )

Esta informação está presente na página de documentação da diretiva AngularJS , embora estejam um pouco espalhadas por toda a página.

O símbolo > não faz parte da sintaxe.

No entanto, <existe como parte das ligações do componente AngularJS e significa ligação unidirecional.

VRPF
fonte
6
Que tal @??
Homer
9
Vale a pena notar que <não é apenas compatível com os componentes no 1.5, mas também é compatível com as diretivas. @Homer ?indica o atributo como opcional .
Jens Bodal
171

> não está na documentação.

< é para ligação unidirecional.

@binding é para passar strings. Essas seqüências suportam {{}}expressões para valores interpolados.

=ligação é para ligação de modelo bidirecional. O modelo no escopo pai está vinculado ao modelo no escopo isolado da diretiva.

& binding é para passar um método para o escopo da sua diretiva, para que possa ser chamado dentro da sua diretiva.

Quando estamos definindo scope: true na diretiva, o Angular js criará um novo escopo para essa diretiva. Isso significa que quaisquer alterações feitas no escopo da diretiva não serão refletidas novamente no controlador pai.

Aravind
fonte
47

< ligação unidirecional

= ligação bidirecional

& função de ligação

@ passar apenas cordas

Timothy.Li
fonte
6
Não faz sentido repetir a mesma resposta, desculpe não a mesma resposta Parece uma informação extraída das respostas acima.
MAC
19
às vezes uma resposta mais curta tende a ser mais prática!
Marwen Trabelsi
Não há necessidade de adicionar informações de lixo se você pode explicar em poucas linhas curtas :)
Marwen Trabelsi
1
Isso teria sido melhor como uma edição para liderar qualquer uma das opções mais votadas.
N-ate
3

Quando criamos uma diretiva de cliente, o escopo da diretiva pode estar no escopo Isolado, significa que a diretiva não compartilha um escopo com o controlador; a diretiva e o controlador têm seu próprio escopo. No entanto, os dados podem ser passados ​​para o escopo da diretiva de três maneiras possíveis.

  1. Os dados podem ser transmitidos como uma string usando a @literal literal, o valor da string de aprovação, uma ligação unidirecional.
  2. Os dados podem ser passados ​​como um objeto usando a =cadeia literal, pass object, de duas maneiras.
  3. Os dados podem ser transmitidos como uma função; a &string literal, chama função externa, pode transmitir dados da diretiva para o controlador.
Bac Nguyen
fonte
2

A documentação do AngularJS sobre diretivas é muito bem escrita para o significado dos símbolos.

Para ser claro, você não pode apenas ter

scope: '@'

em uma definição de diretiva. Você deve ter propriedades às quais essas ligações se aplicam, como em:

scope: {
    myProperty: '@'
}

Eu sugiro fortemente que você leia a documentação e os tutoriais no site. Há muito mais informações que você precisa saber sobre escopos isolados e outros tópicos.

Aqui está uma citação direta da página vinculada acima, sobre os valores de scope:

A propriedade scope pode ser verdadeira, um objeto ou um valor falso:

  • falsy : nenhum escopo será criado para a diretiva. A diretiva usará o escopo de seus pais.

  • true: Um novo escopo filho que herda prototipicamente de seu pai será criado para o elemento da diretiva. Se várias diretivas no mesmo elemento solicitarem um novo escopo, apenas um novo escopo será criado. A nova regra de escopo não se aplica à raiz do modelo, pois a raiz do modelo sempre obtém um novo escopo.

  • {...} (um hash do objeto) : um novo escopo "isolado" é criado para o elemento da diretiva. O escopo 'isolar' difere do escopo normal, pois não herda prototipicamente de seu escopo pai. Isso é útil ao criar componentes reutilizáveis, que não devem ler ou modificar dados acidentalmente no escopo pai.

Recuperado em 13-02-2017 de https://code.angularjs.org/1.4.11/docs/api/ng/service/ $ compile # -scope-, licenciado como CC-by-SA 3.0

Macaco herético
fonte
0

Ocorreu um problema ao vincular um valor a qualquer um dos símbolos no AngularJS 1.6. Não obtive nenhum valor, apenas undefined, embora tenha feito exatamente da mesma maneira que outras ligações no mesmo arquivo que funcionou.

O problema era: meu nome de variável tinha um sublinhado.

Isso falha:

bindings: { import_nr: '='}

Isso funciona:

bindings: { importnr: '='}

(Não está totalmente relacionado à pergunta original, mas esse foi um dos principais resultados de pesquisa quando olhei; espero que isso ajude alguém com o mesmo problema.)

Maurits
fonte