Qual é a diferença entre & vs @ e = in angularJS


Respostas:


375

@permite que um valor definido no atributo de diretiva seja passado para o escopo isolado da diretiva. O valor pode ser uma string simples value ( myattr="hello") ou uma string interpolada AngularJS com expressões incorporadas ( myattr="my_{{helloText}}"). Pense nisso como uma comunicação "unidirecional" do escopo pai para a diretiva filho. John Lindquist tem uma série de pequenos screencasts explicando cada um deles. O Screencast em @ está aqui: https://egghead.io/lessons/angularjs-isolate-scope-attribute-binding

&permite que o escopo isolado da diretiva passe valores para o escopo pai para avaliação na expressão definida no atributo Observe que o atributo diretiva é implicitamente uma expressão e não usa a sintaxe da expressão de chave dupla. Este é mais difícil de explicar em texto. Screencast em & está aqui: https://egghead.io/lessons/angularjs-isolate-scope-expression-binding

=configura uma expressão de ligação bidirecional entre o escopo isolado da diretiva e o escopo pai. Alterações no escopo filho são propagadas para o pai e vice-versa. Pense em = como uma combinação de @ e &. Screencast em = está aqui: https://egghead.io/lessons/angularjs-isolate-scope-two-way-binding

E, finalmente, aqui está um screencast que mostra os três usados ​​juntos em uma única exibição: https://egghead.io/lessons/angularjs-isolate-scope-review



1
Obrigado pela frase de destaque, atualizei minha resposta com os URLs corretos.
cliff.meyers

43
É uma pena que a resposta mais votada esteja vinculada a vídeos atrás de um muro pago quando provavelmente há um monte de conteúdo gratuito por aí que contém as mesmas informações.
BenCr

Há uma série de vídeos que são fornecidos gratuitamente pelo egghead :)
Vatsal

7
menos um para conteúdo pago.
Arel Sapir

109

Eu gostaria de explicar os conceitos da perspectiva da herança do protótipo JavaScript. Espero ajudar a entender.

Existem três opções para definir o escopo de uma diretiva:

  1. scope: false: Padrão angular. O escopo da diretiva é exatamente o escopo pai ( parentScope).
  2. scope: true: Angular cria um escopo para esta diretiva. O escopo herda prototipicamente de parentScope.
  3. scope: {...}: escopo isolado é explicado abaixo.

Especificar scope: {...}define um isolatedScope. Um isolatedScopenão herda propriedades de parentScope, embora isolatedScope.$parent === parentScope. É definido através de:

app.directive("myDirective", function() {
    return {
        scope: {
            ... // defining scope means that 'no inheritance from parent'.
        },
    }
})

isolatedScopenão tem acesso direto a parentScope. Mas às vezes a diretiva precisa se comunicar com o parentScope. Eles se comunicam através de @, =e &. O tópico sobre o uso de símbolos @, =e &estamos a falar de cenários usandoisolatedScope .

Geralmente é usado para alguns componentes comuns compartilhados por páginas diferentes, como Modals. Um escopo isolado evita poluir o escopo global e é fácil de compartilhar entre as páginas.

Aqui está uma diretiva básica: http://jsfiddle.net/7t984sf9/5/ . Uma imagem para ilustrar é:

insira a descrição da imagem aqui

@: ligação unidirecional

@simplesmente passa a propriedade de parentScopepara isolatedScope. É chamado one-way binding, o que significa que você não pode modificar o valor das parentScopepropriedades. Se você estiver familiarizado com a herança do JavaScript, poderá entender facilmente esses dois cenários:

  • Se a propriedade de ligação for um tipo primitivo, como interpolatedPropno exemplo: você pode modificar interpolatedProp, mas parentProp1não seria alterado. No entanto, se você alterar o valor de parentProp1, interpolatedPropserá substituído pelo novo valor (quando $ digest angular).

  • Se a propriedade de ligação for algum objeto, como parentObj: como o que foi passado isolatedScopeé uma referência, a modificação do valor acionará este erro:

    TypeError: Cannot assign to read only property 'x' of {"x":1,"y":2}

=: ligação bidirecional

=é chamado two-way binding, o que significa que qualquer modificação em childScopetambém atualizará o valor em parentScopee vice-versa. Esta regra funciona para primitivos e objetos. Se você alterar o tipo de ligação do parentObjser =, você vai achar que você pode modificar o valor de parentObj.x. Um exemplo típico é ngModel.

&: função de ligação

&permite que a diretiva chame alguma parentScopefunção e transmita algum valor da diretiva. Por exemplo, verifique JSFiddle: & no escopo da diretiva .

Defina um modelo clicável na diretiva como:

<div ng-click="vm.onCheck({valueFromDirective: vm.value + ' is from the directive'})">

E use a diretiva como:

<div my-checkbox value="vm.myValue" on-check="vm.myFunction(valueFromDirective)"></div>

A variável valueFromDirectiveé passada da diretiva para o controlador pai através de {valueFromDirective: ....

Referência: Compreendendo Escopos


Por padrão, as diretivas usam escopo compartilhado. Se a diretiva tiver 'scope: true', ela usará o escopo herdado, no qual o filho poderá ver as propriedades do pai, mas o pai não poderá ver as propriedades internas do filho.
YuMei 24/07/2015

1
AngularJS - Escopos isolados - @ vs = vs & ---------- Pequenos exemplos com explicação estão disponíveis no link abaixo: codeforeach.com/angularjs/angularjs-isolated-scopes-vs-vs
Prashanth

24

Não é meu violino, mas http://jsfiddle.net/maxisam/QrCXh/ mostra a diferença. A peça principal é:

           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:'&'
        }        

17

@ : ligação unidirecional

= : ligação bidirecional

& : ligação de função


5
uma advertência importante para @ não é apenas one-way, mas em vias corda
Shawson

@Shawson: Então, como vincular não-string unidirecional (por exemplo, int ou bool)?
OR Mapper

Se o seu coração está determinado, você pode pegar o valor de @ e converter em int / bool? Caso contrário, eu apenas usaria = ou <
Shawson

7

AngularJS - Escopos isolados - @ vs = vs &


Exemplos curtos com explicação estão disponíveis no link abaixo:

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

@ - ligação unidirecional

Na diretiva:

scope : { nameValue : "@name" }

Em vista:

<my-widget name="{{nameFromParentScope}}"></my-widget>

= - ligação em dois sentidos

Na diretiva:

scope : { nameValue : "=name" },
link : function(scope) {
  scope.name = "Changing the value here will get reflected in parent scope value";
}

Em vista:

<my-widget name="{{nameFromParentScope}}"></my-widget>

& - Chamada de função

Na diretiva:

scope : { nameChange : "&" }
link : function(scope) {
  scope.nameChange({newName:"NameFromIsolaltedScope"});
}

Em vista:

<my-widget nameChange="onNameChange(newName)"></my-widget>

Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.