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.