Чи слід використовувати `this` або` $ range`?


251

Для доступу до функцій контролера використовується дві моделі: thisі $scope.

Що я повинен використовувати і коли? Я розумію this, встановлено на контролер і $scopeє об'єктом у ланцюзі діапазону для переглядів. Але з новим синтаксисом "Controller as Var" ви можете легко використовувати будь-який. Тож я запитую те, що найкраще і який напрямок на майбутнє?

Приклад:

  1. Використання this

    function UserCtrl() {
      this.bye = function() { alert('....'); };
    }
    <body ng-controller='UserCtrl as uCtrl'>
      <button ng-click='uCtrl.bye()'>bye</button>
  2. Використання $scope

    function UserCtrl($scope) {
        $scope.bye = function () { alert('....'); };
    }
    <body ng-controller='UserCtrl'>
        <button ng-click='bye()'>bye</button>

Я особисто вважаю, що this.nameце стає простішим для очей і більш природним порівняно з іншими моделями Javascript OO.

Поради будь ласка?


Використання «це» , здається, новий від Google I / O 2013 m.youtube.com/watch?v=HCR7i5F5L8c Крім того , перевірити цей відповідь: stackoverflow.com/questions/11605917 / ...
AlanW

Чи новий синтаксис "UserCtrl як uCtrl"? Я не бачу це документально на сторінках 1.0.6 або 1.1.4 ngController.
Марк Райкок

Гаразд, це задокументовано на новій сторінці 1.1.5 ngController .
Марк Райкок

1
Кращі роз'яснення щодо $ range
Сай

Відповіді:


229

Обидва мають своє використання. По-перше, якась історія ...

$ range - це "класична" методика, в той час як "Controller as" набагато пізніший (за версією 1.2.0 офіційно, хоча до цього вона з'являлася в нестабільних попередніх випусках).

Обидва працюють прекрасно, і єдина неправильна відповідь - змішати їх в одній програмі без явної причини. Відверто кажучи, змішування їх спрацює, але це просто додасть плутанини. Тому виберіть один і закатайте з ним. Найголовніше - бути послідовним.

Який? Це залежить від вас. Є ще багато прикладів, що мають розмір $, але "контролер як" також набирає пар. Чи один кращий за інший? Це дискусійно. То як ви обираєте?

Комфорт

Я вважаю за краще "контролер як", тому що мені подобається приховувати область $ і піддавати членів від контролера перегляду через посередницький об'єкт. Встановивши це. *, Я можу викрити лише те, що хочу піднести від контролера до перегляду. Ви можете це робити і з $ range, я просто вважаю за краще використовувати для цього стандартний JavaScript. Насправді я кодую це так:

var vm = this;

vm.title = 'some title';
vm.saveData = function(){ ... } ;

return vm;

Це відчуває мене більш чистою і дозволяє легко побачити те, що піддається погляду. Зауважте, я називаю змінну, яку я повертаю "vm", яка розшифровується як viewmodel. Це лише моя умовність.

З $ range я можу робити те ж саме, тому я не додаю та не применшую техніку.

$scope.title = 'some title';
$scope.saveData = function() { ... };

Тож саме від вас залежить.

Ін'єкція

За допомогою $ range мені потрібно вводити $ range в контролер. Мені це не доводиться робити з контролером, якщо тільки мені це не потрібно з якоїсь іншої причини (наприклад, $ трансляція або годинник, хоча я намагаюся уникати годин у контролері).

ОНОВЛЕННЯ Я написав цей пост про два варіанти: http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/


4
Особисто я також дотримуюся вашого підходу, використовуючи vm. Єдиний запах коду, який я підхопив, - це коли вам потрібно спеціально взаємодіяти з областю $, наприклад, передплачуючи або транслюючи події, отримуючи доступ до змінних валідів форми всередині вашого контролера тощо. Це призводить до дещо змішаного середовища, де вам все-таки потрібно ввести $ range навіть якщо ви використовуєте контролер як функцію.
гравці

9
Правильно. У цьому випадку досі використовується $ range, але він більше використовується як послуга. Коли ми вводимо кутові послуги ($ range, $ q тощо), вони надають нам потрібну функцію. $ range дозволяє нам спостерігати, застосовувати, використовувати повідомлення, а також прив'язку даних. І навіть при використанні контролера як, $ range все ще використовується, його щойно абстрагується
Джон Папа

1
var vm = this;вам також потрібно називати це "vm" у поданні? 'контролер як vm'. Вони повинні бути однаковими?
Джавід

2
@JohnPapa - чому шаблони SideWaffle не повертають vm; при використанні Controller As?
Кевін

2
@Kevin Контролери ефективно діють як Ctor і, таким чином, вже повертають "це".
Джон Папа

68

$scopeвидаляється в Angular 2.0. Таким чином, використовуючи thisпідхід, який інші хочуть дотримуватися, оскільки дата виходу Angular 2.0 наближається.


40

Я вважаю, що "у цього" в JavaScript є достатньо проблем, і додавання іншого значення / використання для нього не є гарною ідеєю.

Я б використовував $ range, для наочності.

ОНОВЛЕННЯ

Зараз тут обговорюється синтаксис "контролер як" . Я не фанат, але тепер, коли це більш "офіційна" конструкція AngularJS, вона заслуговує на деяку увагу.


10
Я думаю, що спочатку нам потрібно зрозуміти новий синтаксис "UserCtrl як uCtrl", перш ніж ми зможемо сказати, що вважаємо за краще.
Марк Райкок

Знову "UserCtrl як uCtrl", я згоден, це потрібно розуміти. Я думаю, що це погана ідея з більшості тих же причин, що і аргументи, викладені тут: groups.google.com/forum/#!topic/angular/84selECbp1I
Roy Truelove

4
Якщо ви знайомі з oop в JS, це має ідеальний сенс. Контролер - це клас, а angular використовує нового оператора щоразу, коли створюється контролер. Вам не сподобається, але, якщо є проблеми із використанням "цього", це вводить в оману. Це прийнятний варіант використання для цього.
MJ

$ range не додає ясності. Насправді, може бути дуже важко дізнатися, що відбувається в представленні даних, коли використовується $ range і у вас є вкладені області застосування. Контролер як синтаксис разом із використанням цього додає значно більшої чіткості. З огляду, добре і зрозуміло, з якої області контролера походить метод чи властивість.
ddelrio1986

1
Я згоден з @ ddelrio1986. Просто виникла проблема з вкладками завантажувальної програми та кутовими з використанням var vm = $ range. Вкладки мають власну сферу застосування, тому ви не можете використовувати це так, як ви очікували, але з var vm = це все працює так, як очікувалося.
user441521

11

Я думаю, що Controller як краще, оскільки він дозволяє легше вкладати сфери, як описано тут Тоддом Мотто:

http://toddmotto.com/digging-into-angulars-controller-as-syntax/

Крім того, це забезпечить, що у вас завжди є хоча б один. у вашому обов'язковому вираженні, яке змушує вас слідувати , не прив'язуйтесь до примітивних рекомендацій.

Крім того, ви можете від'єднатись від сфери, яка відходить у 2.0.


7

Кутова документація прямо говорить вам, що використовувати thisрекомендується. Це, крім того, $scopeщо знімається, є мені достатньою причиною, щоб ніколи не користуватися $scope.


4

Програма Jason328 «$ $ видаляється у Angular 2.0» звучить для мене вагомою причиною. І я знайшов ще одну причину , щоб допомогти мені зробити вибір: thisбільш читабельним - коли я бачу , fooCtrl.barв HTML, я відразу знаю , де знайти визначення bar.

Оновлення: недовго після переходу на thisрішення я почав пропускати $scopeспосіб, який потребує меншої кількості тексту


2

Я віддаю перевагу комбінації.

Простий console.log з $ range та "this" після заповнення їх деякими макетними даними покаже вам це.

$ range дозволяє отримати доступ до під кришкою частин контролера, наприклад:

$$ChildScope: null;
$$childHead: null;
$$childTail: null;
$$listenerCount: Object;
$$listeners: Object;
$$nextSibling: Scope;
$$prevSibling: null;
$$watchers: null;
$$watcherCount: 0;
$id: 2;
$parent: Object;
foo: 'bar';

** Властивості та методи з $$ не рекомендується возитися з командою Angular, але $ може бути безпечною грою для того, щоб робити класні речі з $ parent та $ id.

"Це" стає прямо до точки, приєднуючи двосторонні дані та функції. Ви побачите лише те, що додали:

foo: 'bar';

То чому я віддаю перевагу комбінації?

У вкладених програмах ui-router я можу отримати доступ до головного контролера, встановити та викликати універсальні значення та функції всередині дочірнього контролера:

У головному контролері:

// Main Controller
var mainCtrl = this;
mainCtrl.foo = 'Parent at the bar';

У дитячому контролері:

// Child Controller
var mainCtrl = $scope.$parent.mainCtrl;
var childCtrl = this;

// update the parent from within the child
childCtrl.underageDrinking = function(){
    mainCtrl.foo = 'Child at the bar';
}

// And then attach the child back to a property on the parent controller!
mainCtrl.currentCtrl = childCtrl;

Тепер ви можете отримати доступ до батьків зсередини дитини та дитини від батьків!


1

І те й інше працює, але якщо ви застосуєте речі, відповідні за сферою до $ range, і якщо ви застосуєте до контролера речі, відповідні для контролера, ваш код буде легко підтримувати. Людям, які говорять: "Фу просто використовуйте область, забудьте цей контролер як синтаксис" ... Це може працювати так само, але мені цікаво, як ви зможете підтримувати величезний додаток, не втрачаючи при цьому речей.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.