Должен ли я использовать `this` или` $ scope`?

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.

Совет пожалуйста?

SenseDeep
источник
Использование «this» кажется новым с Google I / O 2013 m.youtube.com/watch?v=HCR7i5F5L8c Также проверьте этот ответ: stackoverflow.com/questions/11605917/…
AlanW
Новый синтаксис "UserCtrl as uCtrl"? Я не вижу этого на страницах 1.0.6 или 1.1.4 ngController.
Марк Райкок
Хорошо, это задокументировано на новой странице 1.1.5 ngController .
Марк Райкок
1
Лучшие объяснения для $ scope и этого codetunnel.io/angularjs-controller-as-or-scope
Саи

Ответы:

229

Оба имеют свое применение. Сначала немного истории ...

$ scope - это «классическая» методика, тогда как «controller as» появился намного раньше (официально, начиная с версии 1.2.0, хотя до этого он появлялся в нестабильных предварительных выпусках).

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

Который из? Это зависит от вас. Есть еще много примеров использования $ scope, но "controller as" также набирает обороты. Один лучше другого? Это спорно. Так как вы выбираете?

комфорт

Я предпочитаю «контроллер как», потому что мне нравится скрывать область видимости $ и открывать элементы из контроллера для просмотра через промежуточный объект. Установив это. *, Я могу выставить на экран только то, что я хочу выставить из контроллера. Вы также можете сделать это с помощью $ scope, я просто предпочитаю использовать стандартный JavaScript для этого. На самом деле, я кодирую это так:

var vm = this;

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

return vm;

Это кажется мне чище и позволяет легко увидеть, что подвергается воздействию. Обратите внимание, что я называю переменную, которую я возвращаю, "vm", что означает viewmodel. Это просто мое соглашение.

С $ scope я могу делать то же самое, поэтому я не добавляю и не отвлекаю технику.

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

Так что решать вам там.

впрыскивание

С $ scope мне нужно ввести $ scope в контроллер. Мне не нужно делать это с контроллером как, если только мне это не нужно по какой-то другой причине (например, $ broadcast или watches, хотя я стараюсь избегать watches в контроллере).

ОБНОВЛЕНИЕ Я написал этот пост о 2 вариантах: http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/

Джон Папа
источник
4
Лично я также следую вашему подходу, используя vm. Единственный запах кода, который я уловил, - это когда вам нужно специально взаимодействовать с $ scope, например, подпиской или трансляцией событий, доступом к переменным проверки формы внутри вашего контроллера и т. Д. Это приводит к несколько смешанной среде, в которой вам все еще нужно внедрить $ scope даже если вы используете контроллер в качестве функции.
Бейерс
9
Правильно. В этом случае все еще используется $ scope, но он больше используется как сервис. Когда мы внедряем угловые сервисы ($ scope, $ q и т. Д.), Они предоставляют некоторую необходимую нам функцию. $ scope позволяет нам просматривать, применять, использовать сообщения, а также привязку данных. И даже при использовании контроллера как, $ scope все еще используется, его просто абстрагируют
Джон Папа
1
var vm = this;Вам тоже нужно называть это vm? «Контроллер как VM». Должны ли они быть одинаковыми?
Джавид
2
@JohnPapa - Почему шаблоны SideWaffle не возвращают vm; при использовании контроллера как?
Кевин
2
@Kevin Контроллеры эффективно действуют как Ctor и, таким образом, уже возвращают «это».
Джон Папа
68

$scopeудаляется в Angular 2.0. Таким образом, использование thisбудет подходом, которому хотят следовать другие, поскольку дата выпуска Angular 2.0 приближается.

jason328
источник
40

Мое мнение таково, что «это» в javascript само по себе имеет достаточно проблем, и что добавление другого значения / использования для него не очень хорошая идея.

Для ясности я бы использовал $ scope.

ОБНОВИТЬ

Теперь есть синтаксис «контроллер как», обсуждаемый здесь . Я не фанат, но теперь, когда это более «официальная» конструкция AngularJS, она заслуживает некоторого внимания.

Рой Truelove
источник
10
Я думаю, что сначала нам нужно понять новый синтаксис «UserCtrl as uCtrl», прежде чем мы сможем сказать, какой из них мы считаем лучше.
Марк Райкок
Re 'UserCtrl как uCtrl', я согласен, это нужно понимать. Я думаю, что это плохая идея, по большинству тех же причин, что и приведенные здесь аргументы: groups.google.com/forum/#!topic/angular/84selECbp1I
Roy Truelove
4
Если вы знакомы с oop в JS, это имеет смысл. Контроллер - это класс, и angular использует новый оператор каждый раз, когда создается контроллер. Вы можете не любить его, но указание на наличие проблем с использованием «this» вводит в заблуждение. Это приемлемый вариант использования для этого.
MJ
$ scope ничего не добавляет к ясности. На самом деле может быть очень сложно узнать, что происходит в представлении, когда вы используете $ scope и у вас есть вложенные области видимости. Контроллер как синтаксис наряду с использованием этого добавляет гораздо больше ясности. В представлении хорошо и понятно, из какой области видимости контроллера создается метод или свойство.
ddelrio1986
1
Я согласен с @ ddelrio1986. Только что возникла проблема с вкладками начальной загрузки и с использованием var vm = $ scope. Вкладки имеют собственную область видимости, и поэтому вы не можете использовать это так, как вы ожидаете, но с var vm = this все работает так, как ожидалось.
user441521
11

Я думаю, что Controller As лучше, так как он позволяет более легко вложить области, как описано Тоддом Мотто здесь:

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

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

Плюс вы можете отделиться от сферы, которая уходит в 2.0.

Райан Вице
источник
7

В документации Angular прямо сказано, что thisрекомендуется использовать. Это, в дополнение к тому, $scopeчто удаляется, является достаточным основанием для меня, чтобы никогда не использовать $scope.

tjespe
источник
4

Хорошая причина для меня звучит из-за того, что в Angular 2.0 удалена область $ jason328. И я нашел еще одну причину, чтобы помочь мне сделать выбор: thisболее читабелен - когда я вижу fooCtrl.barв HTML, я сразу знаю, где найти определение bar.

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

ЗЗЫ
источник
2

Я предпочитаю комбинацию.

Простой console.log из $ scope и 'this' после заполнения их некоторыми фиктивными данными покажет вам это.

$ scope позволяет получить доступ к частям контроллера, например:

$$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.

«this» сразу попадает в точку, добавляя данные и функции, связанные с двумя путями. Вы увидите только то, что вы прикрепили:

foo: 'bar';

Так почему я предпочитаю комбинацию?

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

В главном контроллере:

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

В Child Controller:

// 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;

Теперь вы можете получить доступ к родителю изнутри child и child от родителя!

Крейг О. Кертис
источник
1

Оба работают, но если вы примените вещи, которые соответствуют области действия, к $ scope, и если вы примените вещи, которые соответствуют контроллеру, к контроллеру, ваш код будет легко поддерживать. Людям, которые говорят: «Тьфу, просто используйте область видимости, забудьте об этом контроллере как о синтаксисе» ... Он может работать так же, но мне интересно, как вы сможете поддерживать огромное приложение, не упуская из виду.

Ник Мэннинг
источник