Angular.js: SOLICITUD DE COMENTARIOS: `angular.component()` - nombre del controlador de la directiva predeterminada

Creado en 2 ene. 2016  ·  59Comentarios  ·  Fuente: angular/angular.js

Deberíamos usar un valor predeterminado coherente para el nombre del controlador de directivas de un componente cuando se adjunta al alcance. Consulte https://github.com/angular/angular.js/issues/10007#issuecomment -166704255

Actualmente estamos predeterminados en el nombre canónico del componente. Esto no es ideal como

a) los nombres de los componentes pueden volverse largos y difíciles de manejar para su uso en una plantilla
b) es más complicado actualizar automáticamente la plantilla para usar en Angular 2, donde el contexto es el controlador.

Los criterios para el nombre son:

1) debe ser el mismo para todos los componentes
2) debe comenzar con $
3) debe ser corto (2-4 caracteres)

Además, el nombre debe representar lo que realmente se publica en el ámbito.

Algunas de las sugerencias anteriores incluyen:

  • vm : este es el nombre comúnmente utilizado en muchas aplicaciones, pero el controlador no es necesariamente un "modelo de vista"
  • $comp : esta es la sugerencia actual del equipo, pero se puede confundir con comparar y no es tan corta
  • $ctrl - esto se puede confundir con los elementos de control de entrada
  • $this - el controlador no es realmente this en la plantilla, ya que el contexto sigue siendo en realidad el alcance
$compile feedback feature

Comentario más útil

Así que los votos están adentro y se ve así:

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

El claro favorito es $ctrl . Además de ser popular, supera los criterios publicados en la parte superior de este número. Además, no introduce ningún concepto especialmente nuevo. Lo que se refiere realmente es un controlador (un componente/controlador de directivas) que los desarrolladores de Angular ya entienden y, al igual que algunos desarrolladores se han acostumbrado a usar vm en sus directivas, los desarrolladores no tardarán en darse cuenta.

Todos 59 comentarios

c) los programadores tienen la tentación de usar isolate:false y acceder directamente a los controladores de los antepasados.

@drpicox : me siento tentado a decir que prohibimos isolate: false para los componentes creados con este asistente.

Estoy de acuerdo, después de considerar esto:

  • isolate: true cuando la restricción es 'E': para mí son realmente componentes, donde la notación $ctrl tiene un significado completo
  • isolate: false cuando restrict es 'A': para mí son _decorators_, una especie de potenciador de los componentes existentes, en este caso $ctrl choca por lo que la nomenclatura actual está bien

Pero considero que el segundo caso es mejor que ver con los directivos, los _decoradores_ no son frecuentes, suelen ser de bajo nivel, y no aptos para juniors.

Entonces, probablemente sea una buena idea prohibir isolate: false .

En otra línea de pensamiento, sobre _decorators_, una función para obtener el controlador del componente 'E' de la entidad actual debería ser una buena idea, especialmente para escribir _decorators_ genéricos para tratar con cualquier componente actual (requiere fuerzas para saber de antemano qué controlador es y no puedes usar una especie de interfaz de lo que buscas).

Me gusta $cmp , pero encuentro $comp aún mejor, porque es más claro.

Me gusta $cmp , pero encuentro $comp aún mejor, porque es más claro.

Me gusta $comp . Cada vez que veo $cmp pienso en "comparar".

sugerencia diferente: ¿por qué no tener el nombre del componente como el nombre de la instancia del controlador?
ej: perfil de usuario -> scope.userProfile

@tabanliviu Así es como se hace actualmente en master pero @petebacondarwin mencionó en este mismo número, en la primera publicación, por qué es mejor un nombre común.

@mgol :+1: Creo que lo pasé por alto cuando leí el boleto. ¿Debería considerarse este cambio más como un problema de ngUpgrade? Creo que en el contexto de angular 1.x, la implementación actual es una buena solución. ¿Quizás exponer esto como una función de configuración que toma el nombre del componente y genera el nombre del controlador? de esta manera sirve al patrón actual y a una futura ruta de migración.

Tiempo de estacionamiento de bicicletas.

+1 por $ctrl.

Ctrl tiene mucha cultura preexistente en la documentación y ejemplos de Angular 1 como el sufijo "controlador". Intente buscar en Google "Ctrl angular" por si acaso.

La elección actual de derivarlo del nombre del componente es bastante desagradable, ya que tienden a ser bastante largos en las aplicaciones reales.

:+1: para $ctrl , $vm por defecto se siente más como una declaración de cómo se deben usar los controladores.

+1 por $ctrl .

Debatimos esto bastante en el equipo de ng-forward y decidimos que ctrl era un término menos cargado que vm .

Voto por $ctrl y estaría muy feliz si esto anima a la gente a no llamar más a sus controladores vm :P

Oh, también me gustaría agregar eso

esto se puede confundir con elementos de control de entrada

No. Realmente no.

$ctrl

Creo que sería más comprensible e intuitivo para todos.

+1 $ctrl

Otras sugerencias:

  1. $as - como controlador como
  2. $at - como @ - mientras que en el script de café hace referencia a 'este' contexto
  3. $ clase: aunque tiene 5 caracteres, está cerca de la notación de clase de componente ng2.
  4. $prox: ya que conceptualmente, la instancia de Ctrl es un proxy para una capa de servicios
  5. $ctx - atajo para contexto
    Gracias.

Voto por $this porque en ng2 this del controlador es el contexto de la plantilla (y en mi opinión component es muy bueno en el papel de herramienta de transición entre ng1 y ng2).

+1 por $ctrl

También prefiero la propiedad $ctrl , porque representa el controlador del componente.

+1 por $ctrl

+1 por $esto

Incluso iría con this y dejaría caer el $ si no fuera demasiado complicado hacerlo. También es la única opción que no es la abreviatura de otra cosa, y odio las abreviaturas. :)

Iría por $ctrl o $cc (siendo la abreviatura de controlador de componentes)

+1 por $ctrl

Podríamos llamarlo simplemente $troll , tiene un poco de $this y la mitad de $controller . No, es broma, estoy bien con $ctrl . :+1:

$ctrl + 1

$vm

ventajas

  • menos conceptos nuevos
  • pequeño
  • no representa lo que realmente es el objeto (pero los desarrolladores en transición lo obtendrán... y ese es el punto)

Contras

  • no representa lo que realmente es el objeto (pero los desarrolladores en transición lo obtendrán... y ese es el punto)

$ctx - acceso directo al contexto.

Más general que $ctrl , menos anónimo que $vm , sin confusión como $comp o $this .

Eché un vistazo a los motores de plantilla (Jade, Handlebars, Mustache.js, Dust.js, Nunjucks, EJS, etc.) y parece que los nombres context , locals o data se utilizan para el nombre de la variable pasado al método de representación.

Además $ctx , por contexto, no tiene la misma sobrecarga cognitiva que $ctrl (o $this ) y, de hecho, dijiste in Angular 2, where the context is the controller .

@albertosantini : un problema con $ctx es que el contexto real es el alcance actual, al que también se puede acceder directamente mediante this .

$vc - significa Controlador de vista.
Encontré una referencia en los documentos de Apple.

tldr;

"...La clase UIViewController define los métodos y propiedades para administrar sus vistas, manejar eventos..."

Voto fuertemente por $this :

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

_Pros:_

  • La MAYOR ventaja : no necesita hacer ningún ctrl = this dentro de su controlador, para que ambas entidades se vean iguales.
  • Cualquier cosa que no sea $this parece que Angular está introduciendo incluso _"más lenguaje propietario"_, que es una de las quejas populares sobre Angular . Su controlador se contaminará así:
  controller: function() {
    var ctrl = this;

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

en lugar del más limpio, elegante y agnóstico del marco

  controller: function() {
    this.items = [];
    this.text = '';
    this.handleSubmit = function () {
       this.items.push({text: this.text});
       this.text = '';
    };
  • Esta última es una función de JavaScript puro que se puede reutilizar en cualquier lugar con o sin Angular. El primero se vería fuera de contexto en cualquier otro lugar.
  • Tenga en cuenta cómo incluso el resaltador de sintaxis es su amigo en el último fragmento y cómo lo está defendiendo en el primero. La legibilidad del código es un tema importante.
  • Esta sintaxis es similar a React como aparece en su página de destino :
<textarea onChange={this.handleChange}>
  • En React, tanto el contexto DOM como la instancia del controlador se tratan exactamente como las mismas entidades , y React incluso aprovecha eso, afirmando que su enfoque es más simple.
  • Angular seguramente no es React, pero muchas personas están usando o mirando ambos, por lo que una mayor similitud se sentiría más amigable, es decir, menos confusa para ellos.

@dmitriz Un problema con $this en AngularJS es que en la plantilla el contexto (es decir this ) realmente no es el controlador. Parece que en React (y Angular 2) realmente son lo mismo, por lo que tiene sentido usar this (o $this ). En Angular 1, no son lo mismo, por lo que $this en realidad podría causar aún más confusión.

Con respecto al lado de JavaScript de las cosas, es muy común en el código ES5 alias this a otra cosa debido a los problemas de vinculación de this al llamar a métodos gratuitos. Por lo tanto, los controladores a menudo tendrán algo como var that = this todos modos, en cuyo caso también se puede usar var ctrl = this .

Dicho esto, no hay ningún requisito para hacer esto en sus controladores si no lo desea. En mi opinión, es perfectamente razonable usar this internamente en un objeto, pero luego referirse a un objeto con algún otro nombre cuando se usa desde el exterior.

@dmitriz , no es necesario que tenga el mismo alias en el controlador y en la vista (nunca lo tengo). Además, siempre uso var self = this en el controlador, para evitar tener que usar $# .bind(this) para las devoluciones de llamadas, etc.
Entonces, esto no debería ser un problema, en mi opinión.

Respecto a otras opciones:

  • $ctx : No me gusta esto, porque (como mencionó @petebacondarwin ), el controlador no es el contexto de las expresiones.
  • $this : No me gusta esto, porque (en expresiones angulares) this es un alias especial para el alcance actual, por lo que tener this --> scope y $this --> controller sería aún más confuso. (Me hubiera gustado de otra manera.)
  • $vm : No me gusta esto (por las razones ya mencionadas), pero podría aceptarlo si nada cumple mejor con nuestras limitaciones.
  • $cmp : No muy satisfactorio (porque no es 100% preciso), pero lo suficientemente declarativo. Podría ir con él si nada mejor cumple con nuestras limitaciones.
  • $comp : Prefiero $cmp , porque es más corto (y no lo encuentro más "confundible" con compare que $comp ).
  • $ctrl : Me gusta mucho esto. Es bastante breve, declarativo y lo más preciso posible. Siempre he agregado a mis controladores el sufijo ctrl y nunca he presenciado ninguna confusión con ConTRoL (pero las personas con más conocimientos insisten en que ha habido confusión :)). Si decidimos que la confusión no es un problema, definitivamente me quedaría con esto, pero estoy bien con otra cosa.
  • $troll : Necesito pensarlo un poco más. Ciertamente tiene potencial :stuck_out_tongue:
  • Otras opciones ( $as , $at , $cc , $prox , $vc ): Creo que están introduciendo nuevos conceptos y serán más confuso que útil.

Voto por $ctrl , porque _es_ el controlador de directivas. Sencillo.

Contra los otros:

  • $vm -- Como ya se señaló, no es una intención de uso requerida => confusión en la lectura de patrón/código o menos opciones para el desarrollador (obligado a implementar vm)
  • $cmp -- Bueno, ¿no es el componente en sí sino (solo) el controlador? Entonces, ¿realmente engañoso?
  • $this -- También ya mencionado, es confuso. ¿Qué hace que la instancia del controlador sea "esto" en el alcance? Semánticamente, no veo que esto pueda ser... bueno... ¿inteligible?
  • $ctx -- En realidad lo mismo que $this .

También como Pascal ya dijo: no veo confusión con los elementos de control. A menos que Angular2 inyecte todos los elementos DOM/input de esa manera (es decir, $ctrl, $val, $cmbx, etc.), no veo que esto sea un problema.

+1 $ctrl

En la misma línea que los comentarios anteriores:

  • $vm , $as , $at , $cc , $prox , $vc , $ctx ,. ..: introduce nuevos conceptos innecesarios a los programadores
  • $this : debido a que this ya existe, puede resultar confuso para los programadores
  • $cmp o $comp : (mejor primero) debería ser bueno porque enfoca a los programadores en el modelo de componentes, pero es posible que no sean sencillos
  • $ctrl : es justo lo que se publica en el alcance, el controlador, por lo que parece muy claro, fácil de entender y usar

Ya veo, gracias por aclarar, no sabia this = $scope pero, si, eso lo descarta.

Entonces $ctrl suena como la siguiente mejor opción, además de $troll que es :)

+1 por $ctrl : más intuitivo y más genérico

@petebacondarwin Gracias por los detalles.

Entonces +1 por $ctrl .

Prefiero el declarativo $ctrl como nombre predeterminado.

¿Por qué no es bueno?

@petebacondarwin @PascalPrecht

¿Por qué VM no es una buena representación?

(Si ya lo discutió sobre un tema diferente, simplemente enlace a él si puede)

Porque AFAIK, los controladores en Angular están más cerca de View Models que de los controladores clásicos de MVC. pero tal vez me estoy perdiendo algo.

+1 por $vm

Estoy de acuerdo con los puntos de @QuinntyneBrown :

es más corto

pero más importante -

La guía de estilo de @johnpapa es muy popular, y muchas personas que conozco se refieren a ella como parte de su programa de capacitación para "nuevos desarrolladores".

Si cambiamos esto aquí, deberíamos considerar el efecto que tendrá en los nuevos desarrolladores (tal vez enviar un PR a la guía de estilo)

Es por eso que me gusta el nombre "$vm" más corto (por cierto, ¿por qué debe comenzar con $ ? :)

(Por cierto, ¿por qué debe comenzar con $? :)

Los nombres definidos angulares comienzan con $ cuando comparten el espacio de nombres con las definiciones del programador, evita colisiones. En este caso, está definido por Angular y está definido dentro del alcance, donde el programador puede tener sus propias definiciones. Usando $ evitamos la colisión de nombres y Angular se comporta de manera consistente con lo que esperan los programadores.

(@johnpapa) El propósito de esta guía de estilo es brindar orientación sobre la creación de aplicaciones Angular al mostrar las convenciones que uso y, lo que es más importante, por qué las elijo.

Estilo Y032 Use una variable de captura para esto cuando use la sintaxis controllerAs. Elija un nombre de variable consistente como vm, que significa ViewModel.

Así que no importa si es vm , ctrl o troll , solo tiene que ser una variable consistente.
Además, como señalé anteriormente, la idea no es agregar nuevos conceptos: vm significa ViewModel , si no está utilizando View Models o no está familiarizado con él, no lo entenderá. lo que significa vm o ViewModel , lo cual será confuso.

No soy partidario de confundir nombres. Creo que ctrl es confuso. es controlador? control (como control html)? y no es esto para un componente?

Voto por vm o comp . vm se usa comúnmente y es fácil de explicar. comp es nuevo, pero no es difícil de adivinar.

¿Qué tal $ctlr (es decir, CONTROLADOR) en lugar de $ctrl ?

+1 $ gratis

@petebacondarwin Oh, la cantidad de disléxicos (como yo) que nos bombardearán con preguntas sobre esto... :)

@drpicox Gracias por la explicación, veo tus puntos y son válidos. es difícil, pero puedo compartir que, al menos desde mi experiencia, no tuve problemas para enseñar a los desarrolladores la convención "vm" y ayudé a algunas empresas a estructurar su aplicación masiva de esa manera, lo entendieron bastante rápido, pero tal vez yo Estoy solo en esta experiencia.

Pero entiendo tus puntos. de acuerdo con $

Sin embargo, todavía estoy por $ vm, pero también estoy bien con $ comp ...

@wesleycho del equipo Angular UI Bootstrap parece estar fuertemente en contra vm :
https://github.com/angular/angular.js/issues/10007#issuecomment-166707284

+1 por $ctrl

@shairez Comparto completamente su punto sobre tener una convención, soy un arquitecto independiente con decenas de proyectos detrás, la convención vm ayudó mucho, pero todavía tengo algunos problemas. Resulta que hay gente que se resiste a usarlo. Probablemente la resistencia debería ser menor si esta convención viene del mismo Angular, pero estoy seguro que si el nombre fuera $ctrl lo aceptarían tal cual, sin ninguna resistencia. $ctrl es sencillo.

Así que los votos están adentro y se ve así:

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

El claro favorito es $ctrl . Además de ser popular, supera los criterios publicados en la parte superior de este número. Además, no introduce ningún concepto especialmente nuevo. Lo que se refiere realmente es un controlador (un componente/controlador de directivas) que los desarrolladores de Angular ya entienden y, al igual que algunos desarrolladores se han acostumbrado a usar vm en sus directivas, los desarrolladores no tardarán en darse cuenta.

Impresionante, $ctrl lo es!

Problema para 1.4 y versiones anteriores: no se puede nombrar un 'como nombre' con $ctrl

Otra preocupación que me gustaría plantear es que en angular 1.4 e inferior, realmente no podemos usar "como nombres" que comiencen con un signo $ .

Da el siguiente error:
Error: [$controller:ctrlfmt] Badly formed controller string

Algunas empresas tienen problemas para actualizarse a las últimas versiones y les puede llevar varios meses.

Todavía quieren mantenerse al día con las convenciones, por lo que su proceso de actualización será más simple en el futuro.

Para ellos, cambiar de vm a $ctrl es imposible.

¿Qué piensas? ¿alguna sugerencia?

tal vez migrar en fases:
comience con la conversión vm a ctrl
cuando se lance 1.5, "actualice" ctrl a $ctrl

Otra forma posible, aunque detallada, es generar el alias de controllerAs en tiempo de ejecución, 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 ¿Qué pasa con las plantillas?

@shairez Uhmmm, tiene sentido, los símbolos $ están destinados solo para componentes internos angulares ... puede tener algún tipo de compatibilidad con versiones posteriores en el siguiente menor, es bueno.

@drpicox tienes razón ahí :).
Nuevamente, una solución en la que puedo pensar (hacky one...), es "reemplazar" ctrl con $ctrl en la plantilla en tiempo de ejecución/compilación. Eso se puede lograr fácilmente si el proyecto se construye con es6 y módulos. de lo contrario, es una tarea para gulp/grunt/npm en el momento de la compilación.

¿Por qué no usar controllerAs ?
No es una solución ideal (y, de hecho, es posible que debamos revisar RegExp que extrae el identificador de la cadena del controlador (si corresponde), pero usar controllerAs es compatible tanto hacia atrás como hacia adelante :)

(Si alguien quiere tener la oportunidad de actualizar ese identificador extrayendo RegExp, está ahí por cierto).

@gkalpak ese es un buen punto, avanzar en la promoción del uso de la propiedad controllerAs es bueno, ya que creo que cada vez más personas también pasarán a usar componentes en sus versiones 1.4 y anteriores.

Pero creo que podría ser confuso si comenzamos a enseñarle a la gente sobre $ctrl y en algunos casos funciona y en otros no.

Entonces, una compatibilidad con versiones posteriores (no estoy seguro de cómo), ¡es una gran idea!

@shairez ¿has creado (puedes) crear un nuevo problema para rastrear esto?

Creé #13736 que permite $ en el identificador, cuando se usa <ctrl> as <identifier> .
Aún así, los identificadores permitidos son diferentes entre controller: '... as ...' y controllerAs: '...' .

Dicho esto, no estoy seguro de que promocionar controller: '... as $ctrl' sea una buena manera de mantenerse al día con las convenciones. Es mucho más difícil actualizar controller: '... as $ctrl' que controller: '...', controllerAs: '$ctrl' .

Gracias @gkalpak . Estoy de acuerdo en que probablemente deberíamos fomentar el uso de la propiedad controllerAs en lugar del controlador como sintaxis.

Una cosa es: la documentación del componente dice: "Las definiciones de componentes son muy simples y no requieren mucha de la complejidad detrás de la definición de directivas generales".
Otro: el controlador en la directiva solo es necesario si crea directivas complejas que se comunican entre sí. De lo contrario, una función de enlace es más que suficiente (por ejemplo, "use el controlador cuando desee exponer una API a otras directivas. De lo contrario, use el enlace" en la directiva de la Guía del desarrollador y, según mi experiencia, las directivas implementan la misma funcionalidad con el enlace en lugar de los controladores utilizados cientos de veces en ng-repeat son mucho más rápidos.
Entonces...
No encuentro en Componente (directiva "simple") la forma de hacer "simple" (función de enlace), solo la pesada (controlador).
¿Echo de menos algo?
Gracias por la explicación.

@frfancha : la mejora del rendimiento se debe a que no es necesario usar $injector para crear una instancia del controlador, ¿verdad? ¿Quizás tiene algunas medidas de rendimiento que puede proporcionar?

La idea del asistente de componentes es simplificar (en el sentido de LOC) escribir directivas de tipo de componente (aislar, elemento); y más fácil de escribir código que está más en línea con la forma en que se hacen las cosas en Angular 2.

Si hay un problema de rendimiento en una aplicación específica, sería bastante sencillo convertir una directiva de componente para usar el ayudante más general directive .

Creo que debemos echar un vistazo a los otros documentos de API y guías para desarrolladores para asegurarnos de que sean coherentes con el nuevo ayudante component() .

@petebacondarwin Al principio escribimos todas nuestras directivas con el controlador, solo porque se mostró de esta manera en el primer tutorial que seguimos.
Solo después de que descubrimos que se tardaba unos 15 segundos en "abrir" una página determinada con 1000 directivas (5 por "filas" en ng-repeat x 200), leímos más sobre las directivas y comprendimos que los controladores son inútiles si no lo hace " hablar" entre directivas (al requerir el controlador de otra). Después de "reescribir" todo con funciones de enlace en lugar de controladores (reescribir es una gran palabra, ya que solo fue copiar/pegar el código en el enlace en lugar del controlador), el tiempo para mostrar la página fue de 8 segundos.
Tenga en cuenta que estas son medidas de Firefox, en ese momento no usábamos Chrome. Ahora lo usamos y calculo que el tiempo en Chrome es el tercero de Firefox (y el uso de memoria el cuarto (y sin pérdida de memoria, lo cual es genial, en Firefox se sabe que nuestra aplicación es "lenta por la tarde")).
En general, estamos muy contentos con angular (hemos convertido todas nuestras aplicaciones de entrada de datos de la aplicación de Windows Smalltalk a WEB API + angular (en caso de que le interese verlo? A veces estoy en Londres).
Pero estoy sorprendido por la elección del controlador para admitir la "manera simple" de hacer la directiva

gracias @gkalpak !

@petebacondarwin un problema separado ya no es relevante, ¿verdad? (Debido a las relaciones públicas)

Estoy de acuerdo (como escribí), deberíamos educar a las personas para que usen la propiedad controllerAs, pero solo lo mencioné porque predigo que la gente se encontrará con ella.

¿Fue útil esta página
0 / 5 - 0 calificaciones