AngularJS – Por que usar o “Controller as vm”?

Durante todo este fim de semana, fiquei muito aflito, sem entender por que a function de um controlador pai não estava sendo reconhecida por um controlador filho.

Logo percebi que ter meu controlador como vm era a causa:

Claro, tudo parece óbvio agora que nem criança1 nem 2 verão funções em ParentCtrl, e se em vez disso eu tivesse usado o padrão anterior de trabalhar sem VM, e em vez disso tivesse $ escopo, tudo estaria bem.

Então, minha pergunta é: “O que beneficia alguém pelo uso do método” vm “e, se é melhor não usá-lo, como é possível chamar chamadas de function no ParentCtrl?

Obrigado

Uma vantagem de usar o controlador como syntax é que ele permite que você defina seus controladores como uma function simples de construtor de javascript com propriedades e funções expostas diretamente do object instanciado em vez do $ escopo.

Por exemplo:

 function MyController() { var ctl = this; ctl.message = 'You have not clicked anything yet.'; ctl.onClick = function() { ctl.message = 'You clicked something.'; }; return ctl; } ... myModule.controller('MyController', MyController); ... 
{{vm.message}}

Repare que somos capazes de usar um controlador que é simples e antigo javascript, mesmo sem estar vinculado ao angular. Para cenários em que você precisa de dependencies adicionais, como $ scope ou outros serviços, ainda é possível transferi-los facilmente para seu construtor, mas esse padrão estimula menos confusão diretamente em seu escopo $ e também resolve o problema de ocultar variável quando variables ​​são definidas diretamente no escopo.

Em última análise, isso se resume a uma questão de preferência, mas para mim eu realmente gosto de não ter que definir tudo diretamente no escopo e tratar meus controllers como qualquer object javascript antigo o máximo possível.

Aqui está um excelente artigo sobre o uso do controlador como: http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/

Eu costumava usar controlador como syntax vm, mas ultimamente eu tenho me afastado disso. Eu estou achando que quando eu construo páginas complexas com diretivas aninhadas usando isolamento de escopo, a abordagem tradicional do $ escopo é muito mais fácil de trabalhar.

Sua pergunta é uma sobre a qual eu fiquei pensando por um tempo. O único valor real que posso ver é que, quando você usa controladores nesteds em uma página, pode obter referência semântica para cada um dos escopos, de modo que sua marcação fique um pouco mais fácil de ler. Então, por exemplo:

 

Showing{{customers.model.length}} customers with a total of {{orders.model.length}} orders

Fora isso, eu realmente não vejo o valor e se você preferir aninhar com diretivas como eu faço, o valor é rapidamente anulado imho.

O que você está experimentando com este exemplo não é especificamente devido ao uso do controlador como syntax; em vez disso, é devido aos seus objects nesteds escondendo o pai devido à nomenclatura.

O controlador como opção é altamente útil ao trabalhar extensivamente com outras linguagens que compilam para JavaScript como o CoffeeScript ou o TypeScript. Ele também permite que você crie controladores muito mais leves, que podem ser intercambiados com componentes não angulares, devido a não precisar da injeção $ scope. É simplesmente uma syntax alternativa, mas você ainda pode usar $ scope se desejar.

A verdadeira questão aqui é porque as pessoas que escreveram exemplos do controlador como syntax decidiram usar o “as vm”. Tecnicamente, a syntax é projetada para fornecer uma experiência de codificação de estilo MVVM e, portanto, usar “as vm” pode fazer sentido, mas isso expõe o problema que você está vendo. Seu controlador pai é um object chamado vm , e seu object filho também é chamado vm , portanto, o object filho está ocultando o object pai da exibição. Se, ao invés disso, você nomear seus objects de maneira diferente, seu object filho não terá nenhum problema ao acessar o object pai, e será realmente muito claro no código com qual object a propriedade com a qual você está trabalhando é proveniente.

Eu acho que uma das principais vantagens é que ele automaticamente garante que você acabará com um . em suas ligações. Porque a regra de ouro em Angular é que, se você não tem um . nas suas ligações você pode se atirar no pé.

Considere que você tem isso:

  

Isso pode não funcionar como pretendido. Por outro lado, se você usar o SomeController as vm syntax SomeController as vm você acabaria automaticamente com isso:

  

Isso salvará você do problema potencial com a binding de dados não funcionando conforme o esperado.

As razões por trás disso estão na forma como a inheritance de protótipos funciona em JavaScript e foi descrita com muito detalhe aqui: Quais são as nuances do escopo do protótipo / inheritance prototípica no AngularJS?

Pelo que entendi, a principal razão para usar a syntax “controller as vm” é que os controladores em angularjs na verdade servem como modelos (encapsulam dados e fornecem comportamentos), ou visualizam modelos (expõem dados a html) .

Na maioria dos casos, funcionou bem, mas um dos principais fallback que encontrei é que é difícil acessar os dados no controlador pai do controlador filho e a possível solução ( Obter o controlador pai no controlador filho que todos usam a notação ‘controller as vm’ ) não é elegante.