Angular.js: ЗАПРОС НА ОБРАТНУЮ СВЯЗЬ: `angular.component()` - имя контроллера директивы по умолчанию

Созданный на 2 янв. 2016  ·  59Комментарии  ·  Источник: angular/angular.js

Мы должны использовать согласованное значение по умолчанию для имени контроллера директив компонента, когда он прикреплен к области. См. https://github.com/angular/angular.js/issues/10007#issuecomment -166704255.

В настоящее время мы по умолчанию используем каноническое имя компонента. Это не идеально, так как

а) имена компонентов могут стать длинными и громоздкими для использования в шаблоне
б) сложнее автоматически обновлять шаблон для использования в Angular 2, где контекстом является контроллер.

Критерии для имени следующие:

1) он должен быть одинаковым для всех компонентов
2) он должен начинаться с $
3) оно должно быть коротким (2-4 символа)

Кроме того, имя должно представлять то, что на самом деле публикуется в области видимости.

Некоторые из предыдущих предложений включают:

  • vm — это обычно используемое имя во многих приложениях, но контроллер не обязательно является «моделью представления».
  • $comp — это текущее предложение от команды, но его можно спутать со сравнением, и оно не такое короткое.
  • $ctrl — это можно спутать с элементами управления вводом
  • $this — контроллер на самом деле не this в шаблоне, поскольку контекст по-прежнему является областью действия.
$compile feedback feature

Самый полезный комментарий

Итак, голоса подведены, и это выглядит так:

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

Явным фаворитом является $ctrl . Помимо того, что он популярен, он соответствует критериям, опубликованным в начале этого выпуска. Кроме того, он не вводит какой-либо особенно новой концепции. На самом деле речь идет о контроллере (контроллере компонента/директивы), который разработчики Angular уже понимают, и так же, как некоторые разработчики привыкли использовать vm в своих директивах, разработчики не заставят себя долго ждать.

Все 59 Комментарий

c) у программистов возникает соблазн использовать isolate:false и напрямую обращаться к предкам-контроллерам.

@drpicox - у меня возникает соблазн сказать, что мы запрещаем isolate: false для компонентов, созданных с помощью этого помощника.

Я согласен, после рассмотрения этого:

  • isolate: true , когда ограничение равно 'E': для меня они действительно являются компонентами, где нотация $ctrl имеет полное значение
  • isolate: false при ограничении 'A': для меня это _decorators_, своего рода энхансер существующих компонентов, в этом случае $ctrl сталкивается, так что текущая номенклатура в порядке

Но я считаю, что во втором случае лучше обойтись директивами, _декораторы_ встречаются нечасто, обычно низкого уровня и не подходят для юниоров.

Так что, наверное, неплохо забанить isolate: false .

В другом направлении мышления, о _decorators_, функция для получения контроллера компонента «E» текущего объекта должна быть хорошей идеей, особенно для написания общих _decorators_ для работы с любым текущим компонентом (требуются силы, чтобы заранее знать, какой контроллер есть, и вы не можете использовать тот интерфейс, который вы ищете).

Мне нравится $cmp , но $comp еще лучше, потому что он понятнее.

Мне нравится $cmp , но $comp еще лучше, потому что он понятнее.

Мне нравится $comp . Всякий раз, когда я вижу $cmp , я думаю «сравнить».

другое предложение: почему бы не использовать имя компонента в качестве имени экземпляра контроллера?
например: профиль пользователя -> scope.userProfile

@tabanliviu Вот как это сейчас делается на master , но @petebacondarwin упомянул в этом же выпуске, в первом посте, почему обычное имя лучше.

@mgol :+1: Кажется, я упустил это из виду, когда читал билет. Следует ли считать это изменение скорее проблемой ngUpgrade? Я думаю, что в контексте angular 1.x текущая реализация является хорошим решением. Возможно, выставить это как функцию настроек, которая берет имя компонента и выводит имя контроллера? таким образом он обслуживает текущий шаблон и будущий путь миграции.

Время велопарковки.

+1 за $ctrl.

Ctrl имеет много ранее существовавших культур в документации Angular 1 и примеров в качестве суффикса «контроллер». Попробуйте погуглить "угловой Ctrl" для хорошей меры.

Текущий выбор получения его из имени компонента довольно неприятный, поскольку они действительно имеют тенденцию быть довольно длинными в реальных приложениях.

:+1: для $ctrl $vm по умолчанию больше похоже на заявление о том, как следует использовать контроллеры.

+1 за $ctrl .

Мы активно обсуждали это в команде ng-forward и решили, что ctrl менее нагруженный термин, чем vm .

Я голосую за $ctrl , и я был бы очень рад, если бы это побудило людей больше не называть свои контроллеры vm :P

О, я бы еще добавила

это можно спутать с элементами управления вводом

Неа. Не совсем.

$ctrl

Я думаю, что это было бы наиболее понятным и интуитивно понятным для всех.

+1 $ctrl

Другие предложения:

  1. $as - как контроллер как
  2. $at — как @ — в то время как в кофейном скрипте он ссылается на «этот» контекст
  3. $ class - хотя 5 символов, это близко к обозначению класса компонента ng2.
  4. $prox — поскольку концептуально экземпляр Ctrl является прокси для уровня служб.
  5. $ctx — ярлык для контекста
    Спасибо.

Я голосую за $this , потому что в ng2 this контроллера является контекстом шаблона (и, на мой взгляд, component очень хорош в роли инструмента перехода между ng1 и ng2).

+1 за $ctrl

Я также предпочитаю свойство $ctrl , потому что оно представляет контроллер компонента.

+1 за $ctrl

+1 за $это

Я бы даже пошел с this и отказался от $ , если бы это не было слишком сложной задачей. Кроме того, это единственный вариант, который не является сокращением от чего-то еще, а я ненавижу аббревиатуры. :)

Я бы выбрал $ctrl или $cc (это сокращение от контроллера компонентов)

+1 за $ctrl

Мы могли бы назвать это просто $troll , в нем есть немного $this и половина от $controller . Нет, шучу, меня устраивает $ctrl . :+1:

$ Ctrl + 1

$вм

Плюсы

  • меньше новых концепций
  • короткая
  • не представляет, что на самом деле представляет собой объект (но разработчики перехода получат это... и в этом суть)

Минусы

  • не представляет, что на самом деле представляет собой объект (но разработчики перехода получат это... и в этом суть)

$ctx — сокращение для контекста.

Более общий, чем $ctrl , менее анонимный, чем $vm , не вводящий в заблуждение, как $comp или $this .

Я посмотрел на механизмы шаблонов (Jade, Handlebars, Mustache.js, Dust.js, Nunjucks, EJS и т. д.), и мне кажется, что имена context , locals или data используются для имени переменной, передаваемой методу рендеринга.

Кроме того, $ctx , для контекста, не имеет такой же когнитивной перегрузки, как $ctrl (или $this ), и, действительно, вы сказали in Angular 2, where the context is the controller .

@albertosantini - одна проблема с $ctx заключается в том, что фактический контекст - это текущая область, которая также доступна напрямую через this .

$vc — расшифровывается как View Controller.
я нашел ссылку в документах Apple

тлдр;

"...Класс UIViewController определяет методы и свойства для управления вашими представлениями, обработки событий..."

Я решительно голосую за $this :

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

_Плюсы:_

  • БОЛЬШОЕ преимущество : вам не нужно делать ctrl = this внутри вашего контроллера, чтобы обе сущности выглядели одинаково.
  • Все, кроме $this , кажется, что Angular представляет даже _"более проприетарный язык"_, что является одной из популярных жалоб на Angular . Ваш контроллер будет загрязнен следующим образом:
  controller: function() {
    var ctrl = this;

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

вместо более чистого, элегантного и независимого от фреймворка

  controller: function() {
    this.items = [];
    this.text = '';
    this.handleSubmit = function () {
       this.items.push({text: this.text});
       this.text = '';
    };
  • Последний представляет собой чистую функцию JavaScript, которую можно повторно использовать где угодно с Angular или без него. Первый будет выглядеть вне контекста в любом другом месте.
  • Обратите внимание, что даже подсветка синтаксиса является вашим другом в последнем фрагменте и как она сопротивляется в первом. Читабельность кода — важный вопрос.
  • Этот синтаксис похож на React, как показано на их целевой странице :
<textarea onChange={this.handleChange}>
  • В React контекст DOM и экземпляр контроллера рассматриваются как одни и те же объекты , и React даже извлекает выгоду из этого, утверждая, что их подход проще.
  • Angular, конечно, не React, но многие люди используют или смотрят на оба, поэтому большее сходство будет казаться им более дружелюбным, то есть менее запутанным.

@dmitriz Одна проблема с $this в AngularJS заключается в том, что в шаблоне контекст (то есть this ) на самом деле не является контроллером. Кажется, что в React (и Angular 2) это действительно одно и то же, поэтому имеет смысл использовать this (или $this ). В Angular 1 они не совпадают, поэтому $this может вызвать еще большую путаницу.

Что касается JavaScript, в коде ES5 очень часто используется псевдоним this для чего-то еще из-за проблем с привязкой this при вызове бесплатных методов. Таким образом, контроллеры все равно часто будут иметь что-то вроде var that = this , и в этом случае можно также использовать var ctrl = this .

При этом нет необходимости делать это в ваших контроллерах, если вы этого не хотите. IMO вполне разумно использовать this внутри объекта, но затем ссылаться на объект под каким-либо другим именем при использовании его извне.

@dmitriz , вам не обязательно иметь один и тот же псевдоним в контроллере и в представлении (я никогда этого не делаю). Кроме того, я всегда использую var self = this в контроллере, чтобы не использовать .bind(this) для обратных вызовов и т. д.
Так что это не должно быть проблемой, имхо.

Относительно других вариантов:

  • $ctx : мне это не нравится, потому что (как упоминал @petebacondarwin ) контроллер не является контекстом выражений.
  • $this : мне это не нравится, потому что (в выражениях Angular) this — это специальный псевдоним для текущей области, поэтому наличие this --> scope и $this --> controller было бы еще более запутанным. (В противном случае мне бы это понравилось.)
  • $vm : мне это не нравится (по уже упомянутым причинам), но я могу согласиться с этим, если ничто лучше не соответствует нашим ограничениям.
  • $cmp : Не суперудовлетворительно (потому что не на 100% точно), но достаточно декларативно. Мог бы пойти с этим, если ничто лучше не соответствует нашим ограничениям.
  • $comp : я предпочитаю $cmp , потому что он короче (и я не нахожу его более «способным спутать» с compare , чем с $comp ).
  • $ctrl : Мне это очень нравится. Он довольно короткий, декларативный и настолько точный, насколько это возможно. Я всегда добавлял к своим контроллерам суффикс ctrl и никогда не видел путаницы с ConTRoL (но более знающие люди утверждают, что путаница была :)). Если мы решим, что путаница не является проблемой, я определенно выберу это, но меня устраивает и что-то другое.
  • $troll : Нужно еще подумать. У него определенно есть потенциал :stuck_out_tongue:
  • Другие варианты ( $as , $at , $cc , $prox , $vc ): я думаю, что они вводят новые концепции и будут более сбивает с толку, чем помогает.

Я голосую за $ctrl , потому что это _является_ контроллером директив. Простой.

Против остальных:

  • $vm -- Как уже указывалось, это не обязательное намерение использования => либо путаница в чтении шаблона/кода, либо меньший выбор для разработчика (вынужден реализовать vm)
  • $cmp -- Ну не сам компонент, а (только) контроллер? Так на самом деле вводят в заблуждение?
  • $this -- Также уже упоминалось, что это сбивает с толку. Что делает экземпляр контроллера «этим» в области видимости? Семантически я не вижу, что это может быть... ну... понятно?
  • $ctx -- Фактически то же самое, что и $this .

Также, как уже сказал Паскаль: я не вижу путаницы с элементами управления. Если Angular2 не внедряет все элементы DOM/input таким образом (например, $ctrl, $val, $cmbx и т. д.), я не вижу в этом проблемы.

+1 $ctrl

В той же строке, что и предыдущие комментарии:

  • $vm , $as , $at , $cc , $prox , $vc , $ctx ,. ..: вводит программистам новые ненужные понятия
  • $this : поскольку this уже существует, это может сбить с толку программистов.
  • $cmp или $comp : (лучше сначала) это должно быть хорошо, потому что это фокусирует программистов на компонентной модели, но они могут быть не прямолинейными
  • $ctrl : это то, что публикуется в области действия, контроллере, поэтому кажется, что это действительно ясно, легко понять и использовать.

Понятно, спасибо за уточнение, я не знал this = $scope , но да, это исключает.

Тогда $ctrl звучит как следующий лучший выбор, если не считать $troll :)

+1 за $ctrl : самый интуитивно понятный и самый общий

@petebacondarwin Спасибо за подробности.

Так что +1 за $ctrl .

Я предпочитаю декларативное $ctrl в качестве имени по умолчанию.

Почему ничего хорошего?

@petebacondarwin @PascalPrecht

Почему VM не является хорошим представлением?

(Если вы уже обсуждали это по другому вопросу, просто дайте ссылку, если можете)

Поскольку, насколько мне известно, контроллеры в Angular ближе к моделям просмотра, чем к классическим контроллерам из MVC. но может я что-то упускаю.

+1 за $vm

Я согласен с точками @QuinntyneBrown -

это короче.

но важнее -

Руководство по стилю @johnpapa очень популярно, и многие люди, которых я знаю, ссылаются на него как на часть своей программы обучения «новых разработчиков».

Если мы изменим это здесь, мы должны рассмотреть, как это повлияет на новых разработчиков (возможно, отправить PR в руководство по стилю).

Вот почему мне нравится более короткое имя «$vm» (кстати, почему оно должно начинаться с $ ? :)

(Кстати, почему он должен начинаться с $? :)

Имена, определенные в Angular, начинаются с $ , когда они разделяют пространство имен с определениями программиста, это позволяет избежать коллизий. В этом случае он определяется Angular и определяется внутри области видимости, где программист может иметь свои собственные определения. Используя $ , мы избегаем конфликта имен, и Angular ведет себя в соответствии с ожиданиями программистов.

(@johnpapa) Цель этого руководства по стилю — предоставить руководство по созданию приложений Angular, показав соглашения, которые я использую, и, что более важно, почему я их выбираю.

Стиль Y032 Используйте для этого переменную захвата при использовании синтаксиса controllerAs. Выберите согласованное имя переменной, например vm, что означает ViewModel.

Таким образом, не имеет значения, vm , ctrl или troll , это просто должна быть непротиворечивая переменная.
Кроме того, как я указывал ранее, идея не в том, чтобы добавлять новые понятия: vm означает ViewModel , если вы не используете View Models или не знакомы с ним, вы не поймете что означает vm или ViewModel , что может сбить с толку.

Я не любитель путать имена. Я думаю, что ctrl сбивает с толку. Это контроллер? управление (например, управление html)? и разве это не для компонента?

Я голосую либо за vm , либо comp . vm обычно используется и легко объяснимо. comp новое, но нетрудно угадать.

Как насчет $ctlr (т.е. ConTroLleR), а не $ctrl ?

+1 $комп.

@petebacondarwin О, сколько дислектиков (таких как я), которые будут бомбить нас вопросами об этом... :)

@drpicox Спасибо за объяснение, я вижу ваши точки зрения, и они верны. это сложно, но я могу поделиться этим, по крайней мере, из своего опыта, у меня не было проблем с обучением разработчиков соглашению «vm», и я помог нескольким компаниям структурировать свои огромные приложения таким образом, они получили это довольно быстро, но, может быть, я м одинок в этом опыте.

Но я понимаю ваши доводы. согласен с $

Я все еще за $vm, но меня устраивает и $comp...

@wesleycho из команды Angular UI Bootstrap, похоже, категорически против vm :
https://github.com/angular/angular.js/issues/10007#issuecomment -166707284

+1 за $ctrl

@shairez Я полностью разделяю ваше мнение о соглашении, я внештатный архитектор с десятками проектов, соглашение vm очень помогло, но у меня все еще есть некоторые проблемы. Оказывается, есть люди, сопротивляющиеся его использованию. Вероятно, сопротивление должно быть ниже, если это соглашение исходит от самого Angular, но я уверен, что если бы имя было $ctrl , они приняли бы его как есть, без какого-либо сопротивления. $ctrl просто прямо вперед.

Итак, голоса подведены, и это выглядит так:

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

Явным фаворитом является $ctrl . Помимо того, что он популярен, он соответствует критериям, опубликованным в начале этого выпуска. Кроме того, он не вводит какой-либо особенно новой концепции. На самом деле речь идет о контроллере (контроллере компонента/директивы), который разработчики Angular уже понимают, и так же, как некоторые разработчики привыкли использовать vm в своих директивах, разработчики не заставят себя долго ждать.

Круто, $ctrl это!

Проблема для версии 1.4 и ниже: невозможно назвать «как имя» с помощью $ctrl

Еще одна проблема, которую я хотел бы затронуть, заключается в том, что в angular 1.4 и ниже мы не можем использовать «как имена», начинающиеся со знака $ .

Это дает следующую ошибку:
Error: [$controller:ctrlfmt] Badly formed controller string

У некоторых компаний возникают проблемы с обновлением до последних версий, и это может занять несколько месяцев.

Они по-прежнему хотят не отставать от соглашений, поэтому их процесс обновления в будущем будет проще.

Для них переход с vm на $ctrl невозможен.

Как вы думаете? какие-либо предложения?

возможно, мигрировать поэтапно:
начните с преобразования vm в ctrl
когда выйдет версия 1.5, "обновите" ctrl до $ctrl

Другой возможный способ — хотя и многословный — состоит в том, чтобы сгенерировать псевдоним controllerAs во время выполнения, проверяя angular.version . что-то типа:

 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 А как насчет шаблонов?

@shairez Мммм, это имеет смысл, символы $ предназначены только для угловых внутренностей ... может быть, неплохо иметь какую-то прямую совместимость в следующем миноре.

@drpicox , ты прав :).
Опять же, одно решение, которое я могу придумать (хакерское...), это «заменить» ctrl на $ ctrl в шаблоне во время выполнения/сборки. Этого можно легко добиться, если проект построен с использованием es6 и модулей. в противном случае это задача для gulp/grunt/npm во время сборки.

Почему бы просто не использовать controllerAs ?
Это не идеальное решение (и действительно, нам, возможно, придется пересмотреть RegExp, который извлекает идентификатор из строки контроллера (если есть), но использование controllerAs совместимо как назад, так и вперед :)

(Если кто-то хочет попробовать обновить этот идентификатор, извлекая RegExp, это прямо здесь, кстати.)

@gkalpak , это хороший момент, продвижение вперед по продвижению использования свойства controllerAs хорошо, поскольку я полагаю, что все больше и больше людей перейдут на использование компонентов в своих версиях 1.4 и более ранних.

Но я думаю, что это может сбить с толку, если мы начнем учить людей $ctrl , и в некоторых случаях это работает, а в некоторых нет.

Так что прямая совместимость (не знаю как) — отличная идея!

@shairez вы (можете ли вы) создать новую проблему, чтобы отслеживать это?

Я создал # 13736, который позволяет использовать идентификатор $ при использовании <ctrl> as <identifier> .
Тем не менее разрешенные идентификаторы различаются между controller: '... as ...' и controllerAs: '...' .

Тем не менее, я не уверен, что продвижение controller: '... as $ctrl' — это хороший способ не отставать от условностей. Обновить controller: '... as $ctrl' намного сложнее, чем controller: '...', controllerAs: '$ctrl' .

Спасибо @gkalpak - я согласен с тем, что нам, вероятно, следует поощрять использование свойства controllerAs , а не контроллера в качестве синтаксиса.

Во-первых, в документации компонента говорится: «Определения компонентов очень просты и не требуют такой сложности, как определение общих директив».
Еще одно: контроллер в директиве необходим только в том случае, если вы создаете сложные директивы, взаимодействующие друг с другом. В противном случае функции ссылки более чем достаточно (например, «используйте контроллер, когда вы хотите предоставить API другим директивам. В противном случае используйте ссылку» в директиве Руководства разработчика, и из моего опыта директивы, реализующие ту же функциональность со ссылкой вместо контроллеров, используемых несколько сотен раз в ng-repeat гораздо быстрее.
Так...
Я не нахожу в Component ("простая" директива) способ сделать "простой" (функция ссылки), только тяжелый (контроллер).
Я что-то пропустил?
Спасибо за объяснение.

@frfancha - улучшение производительности связано с тем, что не нужно использовать $injector для создания экземпляра контроллера, верно? Возможно, у вас есть какие-то измерения производительности, которые вы можете предоставить?

Идея помощника компонента состоит в том, чтобы упростить (в смысле LOC) написание директив типа компонента (изолировать, элемент); и легче писать код, который больше соответствует тому, как все делается в Angular 2.

Если в конкретном приложении есть проблема с производительностью, было бы довольно просто преобразовать директиву компонента для использования более общего помощника directive .

Я думаю, нам нужно взглянуть на другие документы API и руководства для разработчиков, чтобы убедиться, что они совместимы с новым помощником component() .

@petebacondarwin Вначале мы писали все наши директивы с помощью контроллера только потому, что так было показано в первом уроке, которому мы следовали.
Только после того, как мы обнаружили, что "открытие" определенной страницы с 1000 директивами (5 по "строкам" в ng-repeat x 200) занимает около 15 секунд, мы прочитали больше о директивах и поняли, что контроллеры бесполезны, если вы не " говорить" между директивами (запрашивая контроллер другой). После «переписывания» всего с линк-функциями вместо контроллеров (переписать — громко сказано, так как это было просто копирование/вставка кода в линк вместо контроллера), время отображения страницы составило 8 секунд.
Обратите внимание, что это меры Firefox, в то время мы не использовали Chrome. Теперь мы используем его, и я оцениваю время в Chrome как треть от Firefox (а использование памяти — четвертое (и без утечки памяти, что здорово, в Firefox наше приложение, как известно, «медленно днем)).
В целом мы очень довольны angular (мы преобразовали все наши приложения для ввода данных из приложения Windows Smalltalk в WEB API + angular (на случай, если вам будет интересно это увидеть? Я иногда бываю в Лондоне).
Но я удивлен выбором контроллера для поддержки «простого способа» сделать директиву

спасибо @gkalpak !

@petebacondarwin отдельная проблема больше не актуальна, верно? (из-за пиара)

Я согласен (как я уже писал), мы должны обучать людей использовать свойство controllerAs, но я только что упомянул об этом, потому что я предсказываю, что люди столкнутся с этим.

Была ли эта страница полезной?
0 / 5 - 0 рейтинги