Angular.js: PEDIDO DE FEEDBACK: `angular.component()` - nome do controlador de diretiva padrão

Criado em 2 jan. 2016  ·  59Comentários  ·  Fonte: angular/angular.js

Devemos usar um valor padrão consistente para o nome do controlador de diretiva de um componente quando ele estiver anexado ao escopo. Consulte https://github.com/angular/angular.js/issues/10007#issuecomment -166704255

Atualmente estamos padronizando o nome canônico do componente. Isso não é o ideal como

a) nomes de componentes podem se tornar longos e difíceis de serem usados ​​em um modelo
b) é mais complicado atualizar automaticamente o template a ser usado em Angular 2, onde o contexto é o controlador.

Os critérios para o nome são:

1) deve ser o mesmo para todos os componentes
2) deve começar com $
3) deve ser curto (2-4 caracteres)

Além disso, o nome deve representar o que realmente está sendo publicado no escopo.

Algumas das sugestões anteriores incluem:

  • vm - este é o nome comumente usado em muitos aplicativos, mas o controlador não é necessariamente um "modelo de visualização"
  • $comp - esta é a sugestão atual da equipe, mas pode ser confundida com comparar e não é tão curta
  • $ctrl - isso pode ser confundido com elementos ConTROL de entrada
  • $this - o controlador não é realmente this no modelo, pois o contexto ainda é o escopo
$compile feedback feature

Comentários muito úteis

Então os votos estão dentro e fica assim:

$comp  4
$cmp   2
$ctrl  19
$vm    3
$this  3
$ctx   2
$vc    1

O favorito claro é $ctrl . Além de ser popular, ele atende aos critérios postados no início desta edição. Além disso, não introduz nenhum conceito particularmente novo. O que está sendo referido realmente é um controlador (um controlador de componente/diretiva) do qual os desenvolvedores Angular já entendem e, assim como alguns desenvolvedores se acostumaram a usar vm em suas diretivas, não demorará muito para os desenvolvedores usarem para este padrão.

Todos 59 comentários

c) os programadores são tentados a usar isolate:false e acessar diretamente os controladores ancestrais.

@drpicox - Estou tentado a dizer que banimos isolate: false para componentes criados usando este auxiliar.

Eu concordo, depois de considerar isso:

  • isolate: true quando restrito é 'E': para mim eles são verdadeiramente componentes, em que a notação $ctrl tem todo o significado
  • isolate: false quando restrito é 'A': para mim eles são _decorators_, uma espécie de potenciador dos componentes existentes, neste caso $ctrl colide então a nomenclatura atual está bem

Mas considero que o segundo caso é melhor fazer com diretivas, _decorators_ não são frequentes, geralmente de baixo nível e não são adequados para juniores.

Então provavelmente é uma boa ideia banir isolate: false .

Em outra linha de pensamento, sobre _decorators_, uma função para obter o controlador do componente 'E' da entidade atual deve ser uma boa idéia, especialmente para escrever _decorators_ genéricos para lidar com qualquer componente atual (requer forças para saber antecipadamente qual controlador é e você não pode usar um tipo de interface do que você está procurando).

Eu gosto de $cmp , mas acho $comp ainda melhor, porque é mais claro.

Eu gosto de $cmp , mas acho $comp ainda melhor, porque é mais claro.

Eu gosto de $comp . Sempre que vejo $cmp penso em "comparar".

sugestão diferente: por que não ter o nome do componente como o nome da instância do controlador?
ex: perfil de usuário -> scope.userProfile

@tabanliviu É assim que é feito atualmente em master mas @petebacondarwin mencionou nesta mesma edição, no primeiro post, por que um nome comum é melhor.

@mgol :+1: Acho que ignorei isso quando li o bilhete. Essa mudança deve ser considerada mais um problema do ngUpgrade? Acho que no contexto do angular 1.x a implementação atual é uma boa solução. Talvez expondo isso como uma função de configurações que recebe o nome do componente e gera o nome do controlador? dessa forma, atende ao padrão atual e a um caminho de migração futuro.

Tempo de bicicleta.

+1 para $ctrl.

Ctrl tem muita cultura pré-existente na documentação do Angular 1 e exemplos como o sufixo "controlador". Tente pesquisar "ctrl angular" no Google para uma boa medida.

A escolha atual de derivá-lo do nome do componente é bastante desagradável, pois eles de fato tendem a ficar muito longos em aplicativos reais.

:+1: for $ctrl , $vm como padrão parece mais uma declaração de como os controladores devem ser usados.

+1 por $ctrl .

Debatemos isso bastante na equipe ng-forward e decidimos que ctrl era um termo menos carregado do que vm .

Eu voto em $ctrl e ficaria muito feliz se isso encorajasse as pessoas a não chamarem mais seus controladores vm :P

Ah, eu também gostaria de adicionar isso

isso pode ser confundido com elementos de entrada ConTROL

Não. Na verdade.

$ctrl

Acho que seria mais compreensível e intuitivo para todos.

+1 $ctrl

Outras sugestões:

  1. $as - como o controlador as
  2. $at - como @ - enquanto no script de café faz referência ao contexto 'este'
  3. $class - embora tenha 5 caracteres, está próximo da notação de classe do componente ng2.
  4. $prox - já que conceitualmente, a instância Ctrl é um proxy para uma camada de serviços
  5. $ctx - atalho para contexto
    Obrigado.

Eu voto em $this porque em ng2 this do controlador é o contexto do modelo (e na minha opinião component é muito bom no papel de ferramenta de transição entre ng1 e ng2).

+1 para $ctrl

Eu também prefiro a propriedade $ctrl , porque ela representa o controlador do componente.

+1 para $ctrl

+1 para $isto

Eu até iria com this e largaria o $ se não fosse muito difícil fazer isso. É também a única opção que não é curta para outra coisa, e eu odeio abreviações. :)

Eu iria para $ctrl ou $cc (sendo curto para controlador de componente)

+1 para $ctrl

Poderíamos chamar de $troll , tem um pouco de $this e metade de $controller . Não, estou brincando, estou bem com $ctrl . :+1:

$ctrl + 1

$vm

Prós

  • menos novos conceitos
  • curto
  • não representa o que o objeto realmente é (mas os desenvolvedores em transição o entenderão ... e esse é o ponto)

Contras

  • não representa o que o objeto realmente é (mas os desenvolvedores em transição o entenderão ... e esse é o ponto)

$ctx - atalho para contexto.

Mais geral que $ctrl , menos anônimo que $vm , não confuso como $comp ou $this .

Dei uma olhada nos motores de template (Jade, Handlebars, Mustache.js, Dust.js, Nunjucks, EJS, etc.) e parece que os nomes context , locals ou data são usados ​​para o nome da variável passado para o método de renderização.

Também $ctx , por contexto, não tem a mesma sobrecarga cognitiva que $ctrl (ou $this ) e, de fato, você disse in Angular 2, where the context is the controller .

@albertosantini - um problema com $ctx é que o contexto real é o escopo atual, que também é acessível diretamente por this .

$vc - significa View Controller.
eu encontrei uma referência nos documentos da apple

tldr;

"...A classe UIViewController define os métodos e propriedades para gerenciar suas visualizações, manipular eventos ..."

Eu voto fortemente em $this :

<textarea ng-change="$this.handleChange">

_Prós:_

  • MAIOR vantagem : Você não precisa fazer nenhum ctrl = this dentro do seu Controller, para que ambas as entidades pareçam iguais.
  • Qualquer coisa diferente de $this parece que o Angular está introduzindo ainda _"linguagem mais proprietária"_, que é uma das reclamações populares sobre o Angular . Seu controlador ficará poluído assim:
  controller: function() {
    var ctrl = this;

    ctrl.items = [];
    ctrl.text = '';
    ctrl.handleSubmit = function () {
        ctrl.items.push({text: ctrl.text});
        ctrl.text = '';
    };
  }

em vez do mais limpo, elegante e agnóstico de estrutura

  controller: function() {
    this.items = [];
    this.text = '';
    this.handleSubmit = function () {
       this.items.push({text: this.text});
       this.text = '';
    };
  • O último é uma função JavaScript pura que pode ser reutilizada em qualquer lugar com ou sem Angular. O primeiro ficaria fora de contexto em qualquer outro lugar.
  • Observe como até mesmo o marcador de sintaxe é seu amigo no último trecho e como ele está lutando contra você no primeiro. A legibilidade do código é uma questão importante.
  • Esta sintaxe é semelhante ao React como aparece em sua página de destino :
<textarea onChange={this.handleChange}>
  • No React, tanto o contexto DOM quanto a instância do Controller são tratados exatamente como as mesmas entidades , e o React ainda capitaliza isso, alegando que sua abordagem é mais simples.
  • Angular certamente não é React, mas muitas pessoas estão usando ou olhando para ambos, então mais similaridade seria mais amigável ou menos confuso para eles.

@dmitriz Um problema com $this no AngularJS, é que no template o contexto (ie this ) realmente não é o controller. Parece que em React (e Angular 2) eles realmente são a mesma coisa e então faz sentido usar this (ou $this ). No Angular 1, eles não são os mesmos e, portanto $this pode causar ainda mais confusão.

Em relação ao lado JavaScript das coisas, é muito comum no código ES5 alias this para outra coisa por causa dos problemas de ligação de this ao chamar métodos livres. Portanto, os controladores ainda terão algo como var that = this qualquer maneira, nesse caso também se pode usar var ctrl = this .

Dito isto, não há necessidade de fazer isso em seus controladores, se você não quiser. É perfeitamente razoável IMO usar this internamente em um objeto, mas depois se referir a um objeto por algum outro nome ao usá-lo de fora.

@dmitriz , você não precisa ter o mesmo alias no controller e na view (eu nunca tenho). Além disso, sempre uso var self = this no controlador, para evitar ter que .bind(this) para retornos de chamada etc.
Então, isso não deve ser um problema, imo.

Sobre outras opções:

  • $ctx : Eu não gosto disso, porque (como @petebacondarwin mencionou), o controlador não é o contexto das expressões.
  • $this : Eu não gosto disso, porque (em expressões angulares) this é um alias especial para o escopo atual, então ter this --> scope e $this --> controller seria ainda mais confuso. (Eu teria gostado de outra forma.)
  • $vm : Eu não gosto disso (por motivos já mencionados), mas eu poderia continuar se nada melhor atendesse às nossas restrições.
  • $cmp : Não super-satisfatório (porque não é 100% preciso), mas declarativo o suficiente. Poderia ir com ele se nada melhor atendesse às nossas restrições.
  • $comp : prefiro $cmp , porque é mais curto (e não acho mais "confundível" com compare do que $comp ).
  • $ctrl : Eu gosto muito disso. É bastante curto, declarativo e o mais preciso possível. Eu sempre sufixei meus controladores com ctrl e nunca testemunhei nenhuma confusão com ConTRoL (mas pessoas mais experientes insistem que houve confusão :)). Se decidirmos que confusão não é um problema, eu definitivamente vou com isso, mas estou bem com outra coisa.
  • $troll : Precisa pensar um pouco mais. Certamente tem potencial :stuck_out_tongue:
  • Outras opções ( $as , $at , $cc , $prox , $vc ): Acho que eles estão introduzindo novos conceitos e serão mais confuso do que útil.

Estou votando em $ctrl , porque _é_ o controlador de diretivas. Simples.

Contra os outros:

  • $vm -- Como já apontado não é uma intenção de uso obrigatória => ou confusão na leitura de padrão/código ou menos escolha para o desenvolvedor (forçado a implementar vm)
  • $cmp -- Bem, não é o componente em si, mas (somente) o controlador? Então, realmente enganosa?
  • $this -- Também já mencionado, é confuso. O que a instância do controlador faz com que seja "isto" no escopo? Semanticamente, não vejo que isso possa ser... bem... inteligível?
  • $ctx -- Na verdade o mesmo que $this .

Também como o Pascal já disse: não vejo confusão com elementos de controle. A menos que o Angular2 injete todos os elementos DOM/input dessa maneira (ou seja, $ctrl, $val, $cmbx e assim por diante), não vejo isso como um problema.

+1 $ctrl

Na mesma linha dos comentários anteriores:

  • $vm , $as , $at , $cc , $prox , $vc , $ctx ,. ..: introduz novos conceitos desnecessários aos programadores
  • $this : porque this já existe, pode ser confuso para os programadores
  • $cmp ou $comp : (melhor primeiro) deve ser bom porque foca os programadores no modelo de componentes, mas eles podem não ser diretos
  • $ctrl : é apenas o que está sendo publicado no escopo, o controlador, então parece muito claro fácil de entender e usar

Entendo, obrigado por esclarecer, eu não sabia this = $scope mas, sim, isso exclui.

Então $ctrl soa como a próxima melhor escolha, além de $troll que é :)

+1 por $ctrl : mais intuitivo e mais genérico

@petebacondarwin Obrigado pelos detalhes.

Então +1 por $ctrl .

Eu prefiro o declarativo $ctrl como o nome padrão.

Por que não é bom?

@petebacondarwin @PascalPrecht

Por que a VM não é uma boa representação?

(Se você já discutiu sobre uma questão diferente, apenas vincule-a se puder)

Como o AFAIK, os controladores em Angular estão mais próximos dos modelos de visualização, em vez dos controladores clássicos do MVC. mas talvez eu esteja perdendo alguma coisa.

+1 por $vm

Eu concordo com os pontos de @QuinntyneBrown -

é mais curto.

mas mais importante -

O guia de estilo do @johnpapa é muito popular, e muitas pessoas que conheço se referem a ele como parte de seu programa de treinamento de "novos desenvolvedores".

Se mudarmos isso aqui, devemos considerar o efeito que isso terá em novos desenvolvedores (talvez envie um PR para o guia de estilo)

É por isso que eu gosto do nome "$vm" mais curto (BTW, por que deve começar com $ ? :)

(BTW, por que deve começar com $ ? :)

Nomes definidos em angular começam com $ quando compartilham o espaço de nomes com as definições do programador, evitando colisões. Neste caso, é definido pelo Angular e é definido dentro do escopo, onde o programador pode ter suas próprias definições. Usando $ evitamos a colisão de nomes e o Angular se comporta de forma consistente com o que os programadores esperam.

(@johnpapa) O objetivo deste guia de estilo é fornecer orientação sobre a criação de aplicativos Angular, mostrando as convenções que uso e, mais importante, por que as escolho.

Estilo Y032 Use uma variável de captura para isso ao usar a sintaxe controllerAs. Escolha um nome de variável consistente, como vm, que significa ViewModel.

Portanto, não importa se é vm , ctrl ou troll apenas tem que ser uma variável consistente.
Além disso, como apontei anteriormente, a ideia não é adicionar novos conceitos: vm significa ViewModel , se você não estiver usando o View Models ou não estiver familiarizado com ele, não entenderá o que vm ou ViewModel significa, o que será confuso.

Não sou fã de nomes confusos. Acho que ctrl é confuso. É controlador? controle (como controle html)? e isso não é para um componente?

Eu voto em vm ou comp . vm é comumente usado e fácil de explicar. comp é novo, mas não é difícil de adivinhar.

Que tal $ctlr (ou seja, ConTroLleR) em vez de $ctrl ?

+1 $comp

@petebacondarwin Ah a quantidade de disléxicos (como eu) que vão nos bombardear com questões sobre isso... :)

@drpicox Obrigado pela explicação, vejo seus pontos e eles são válidos. é difícil, mas posso compartilhar isso pelo menos da minha experiência, não tive problemas em ensinar aos desenvolvedores a convenção "vm" e ajudei algumas empresas a estruturar seu aplicativo massivo dessa maneira, eles entenderam muito rápido, mas talvez eu ' m sozinho nesta experiência.

Mas eu entendo seus pontos. concordo com $

Ainda estou com $vm, mas também estou bem com $comp ...

@wesleycho da equipe Angular UI Bootstrap parece ser fortemente contra vm :
https://github.com/angular/angular.js/issues/10007#issuecomment -166707284

+1 por $ctrl

@shairez Compartilho completamente seu ponto de vista sobre ter uma convenção, sou um arquiteto freelancer com dezenas de projetos por trás, a convenção vm ajudou muito, mas ainda tenho alguns problemas. Acontece que há pessoas resistindo a usá-lo. Provavelmente a resistência deveria ser menor se essa convenção vier do próprio Angular, mas tenho certeza que se o nome fosse $ctrl eles aceitariam como está, sem nenhuma resistência. $ctrl é apenas direto.

Então os votos estão dentro e fica assim:

$comp  4
$cmp   2
$ctrl  19
$vm    3
$this  3
$ctx   2
$vc    1

O favorito claro é $ctrl . Além de ser popular, ele atende aos critérios postados no início desta edição. Além disso, não introduz nenhum conceito particularmente novo. O que está sendo referido realmente é um controlador (um controlador de componente/diretiva) do qual os desenvolvedores Angular já entendem e, assim como alguns desenvolvedores se acostumaram a usar vm em suas diretivas, não demorará muito para os desenvolvedores usarem para este padrão.

Incrível, $ctrl é!

Problema para 1.4 e inferior - não é possível nomear um 'como nome' com $ctrl

Outra preocupação que gostaria de levantar é que em angular 1.4 e inferior, não podemos realmente usar "como nomes" começando com um sinal $ .

Dá o seguinte erro:
Error: [$controller:ctrlfmt] Badly formed controller string

Algumas empresas têm problemas para atualizar para as versões mais recentes e podem levar vários meses.

Eles ainda querem manter as convenções, então seu processo de atualização será mais simples no futuro.

Para eles, mudar de vm para $ctrl é impossível.

O que você acha? alguma sugestão?

talvez migrar em fases:
comece convertendo vm para ctrl
quando a versão 1.5 for lançada, "atualize" ctrl para $ctrl

Outra maneira possível - embora detalhada - é gerar o alias controllerAs em tempo de execução, verificando angular.version . algo como:

 angular
        .module('github')
        .directive('issueThread', issueThread);

    /* <strong i="14">@ngInject</strong> */
    function issueThread () {
        // this can be required as a module if using some module loader
        // or - another way is using global on angular namespace (i know it a bad practice - hwoever just to indicate reuse of this check 
        let prefix = angular.version.minor === 5 ? '$' : '';
        let controllerAs = prefix + 'ctrl';
        // with template strings
        var controllerAs = `${prefix}ctrl`;

        var directive = {
            controller: controller,
            restrict: 'E'
        };
        return directive;

        function controller() {
        }
    }

@orizens E os modelos?

@shairez Uhmmm faz sentido, os símbolos $ são destinados apenas a internos angulares ... pode ter algum tipo de compatibilidade direta no próximo menor é bom.

@drpicox você tem um ponto aí :).
Novamente, uma solução em que posso pensar (hacky one ...), é "substituir" ctrl por $ ctrl no modelo em tempo de execução / compilação. Isso pode ser alcançado facilmente se o projeto for construído com es6 e módulos. caso contrário, é uma tarefa para gulp/grunt/npm em tempo de compilação.

Por que não usar controllerAs ?
Não é uma solução ideal (e, de fato, podemos precisar revisar o RegExp que extrai o identificador da string do controlador (se houver), mas usar controllerAs é compatível com versões anteriores e posteriores :)

(Se alguém quiser ter uma chance de atualizar esse identificador extraindo RegExp, está ali mesmo.)

@gkalpak isso é um bom ponto, avançar promovendo o uso da propriedade controllerAs é bom, pois mais e mais pessoas também farão a transição para o uso de componentes em suas versões 1.4 e inferiores, acredito.

Mas, acho que pode ser confuso se começarmos a ensinar as pessoas sobre $ctrl e em alguns casos funciona e em outros não.

Portanto, uma compatibilidade com versões anteriores (não sei como) é uma ótima ideia!

@shairez você (você pode) criar um novo problema para rastrear isso?

Eu criei #13736 que permite $ no identificador, ao usar <ctrl> as <identifier> .
Ainda assim, os identificadores permitidos são diferentes entre controller: '... as ...' vs controllerAs: '...' .

Dito isso, não tenho certeza de que promover controller: '... as $ctrl' seja uma boa maneira de acompanhar as convenções. É muito mais difícil atualizar controller: '... as $ctrl' do que controller: '...', controllerAs: '$ctrl' .

Obrigado @gkalpak - Concordo que provavelmente devemos encorajar o uso da propriedade controllerAs em vez do controlador como sintaxe.

Uma coisa é: a documentação do componente diz: "As definições de componentes são muito simples e não requerem muita complexidade por trás da definição de diretivas gerais".
Outra: controlador na diretiva só é necessário se você construir diretivas complexas conversando entre si. Caso contrário, uma função de link é mais que suficiente (por exemplo, "use o controlador quando quiser expor uma API a outras diretivas. Caso contrário, use o link" na diretiva do Guia do desenvolvedor e, pela minha experiência, as diretivas implementam a mesma funcionalidade com link em vez de controladores usados ​​algumas centenas de vezes em ng-repeat são muito mais rápidos.
Assim...
Não encontro em Componente (diretiva "simples") a forma de fazer "simples" (função link), apenas o pesado (controlador).
Eu sinto falta de alguma coisa?
Obrigada pelo esclarecimento.

@frfancha - a melhoria de desempenho se deve ao fato de não precisar usar o $injector para instanciar o controlador, certo? Talvez você tenha algumas medidas de desempenho que possa fornecer?

A idéia do auxiliar de componente é tornar mais simples (no sentido LOC) escrever diretivas de tipo de componente (isolar, elemento); e mais fácil de escrever código que esteja mais alinhado com a forma como as coisas são feitas no Angular 2.

Se houver um problema de desempenho em um aplicativo específico, seria bastante simples converter uma diretiva de componente para usar o auxiliar directive mais geral.

Acho que precisamos dar uma olhada nos outros documentos da API e guias do desenvolvedor para garantir que eles sejam consistentes com o novo auxiliar component() .

@petebacondarwin No início escrevemos todas as nossas diretivas com controller, apenas porque foi mostrado assim no primeiro tutorial que seguimos.
Somente depois que descobrimos que demorou cerca de 15 segundos para "abrir" uma determinada página com 1000 diretivas (5 por "linhas" em ng-repeat x 200), lemos mais sobre diretivas e entendemos que os controladores são inúteis se você não " falar" entre diretivas (exigindo o controlador de outra). Depois de "reescrever" tudo com funções de link em vez de controladores (reescrever é uma palavra grande, pois era apenas copiar/colar o código no link em vez do controlador), o tempo para exibir a página era de 8 segundos.
Observe que essas são medidas do Firefox, naquela época não usávamos o Chrome. Agora usamos e estimo que o tempo no Chrome seja o terceiro do Firefox (e o uso de memória o quarto (e sem vazamento de memória, o que é ótimo, no Firefox nosso aplicativo é conhecido por ser "lento à tarde)).
Geralmente estamos muito felizes com o angular (convertemos todos os nossos aplicativos de entrada de dados do aplicativo do Windows Smalltalk para a API WEB + angular (caso isso lhe interesse ver? Às vezes estou em Londres).
Mas estou surpreso com a escolha do controlador para suportar a "maneira simples" de fazer diretiva

obrigado @gkalpak !

@petebacondarwin uma questão separada não é mais relevante, certo? (Por causa do PR)

Concordo (como escrevi), devemos educar as pessoas para usar a propriedade controllerAs, mas acabei de mencioná-la porque prevejo que as pessoas a encontrarão.

Esta página foi útil?
0 / 5 - 0 avaliações