#6 Controller as синтаксис в AngularJS

poster
В обычном подходе AngularJS в шаблоне часто непонятно из какого контроллера вызывается метод. В этом уроке мы разберем альтернативных подход к описанию контроллера используя this и controller as синтаксис.
Понравилось? Поделитесь с друзьями!
Понравилось?
Поделитесь с друзьями!
Комментарии
Текст видео

Всем привет. Сегодня мы с вами разберем, что такое controller as синтаксис и почему scope это плохо.

Давайте создадим пример, который немного будет напоминать пример из предыдущего урока.

<div ng-controller="mainCtrl">
  <div ng-controller="firstCtrl">
    <div ng-controller="secondCtrl">
      {{myLesson}}
    </div>
  </div>
</div>

Создадим контроллер mainCtrl. Вложим в него контроллер firstCtrl, а в него secondCtrl. Внутри выведем переменную myLesson.

Теперь опишем под них контроллеры.

var app = angular.module('app', []);

app.controller('mainCtrl', function ($scope) {
});

app.controller('firstCtrl', function ($scope) {
});

app.controller('secondCtrl', function ($scope) {
});

У нас сейчас достаточно стандартный пример с вложенными контроллерами. Теперь в $scope запишем переменную myLesson

var app = angular.module('app', []);

app.controller('mainCtrl', function ($scope) {
});

app.controller('firstCtrl', function ($scope) {
});

app.controller('secondCtrl', function ($scope) {
    $scope.myLesson = 'Lesson';
});

Если мы посмотрим в браузер, то у нас вывелась строка Lesson. Что будет, если мы перенесем этот код в firstCtrl?

var app = angular.module('app', []);

app.controller('mainCtrl', function ($scope) {
});

app.controller('firstCtrl', function ($scope) {
    $scope.myLesson = 'Lesson';
});

app.controller('secondCtrl', function ($scope) {
});

Все точно так же будет работать, даже, если мы его перенесем в mainCtrl. Это конечно хорошо, но у нас появилось усложнение кода, потому что мы не знаем, из какого конкретно контроллера этот код будет вызван и где находится эта переменная - в secondCtrl, firstCtrl или mainCtrl. Из-за этого код становится более сложным.

Чтобы этого избежать, используется controller as синтаксис.

<div ng-controller="mainCtrl as mainCtrl">
  <div ng-controller="firstCtrl as firstCtrl">
    <div ng-controller="secondCtrl as secondCtrl">
      {{myLesson}}
    </div>
  </div>
</div>

Что это значит? Это значит, что в шаблоне у нас теперь появляется переменная mainCtrl, firstCtrl и secondCtrl, которые связаны с this внутри каждого контроллера. Давайте попробуем. Во-первых, удаляем $scope во всех трех контроллерах.

var app = angular.module('app', []);

app.controller('mainCtrl', function () {
});

app.controller('firstCtrl', function () {
});

app.controller('secondCtrl', function () {
});

Теперь мы можем использовать this, вместо того, чтобы использовать $scope.

app.controller('secondCtrl', function () {
    this.myLesson = 'Lesson';
});

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

<div ng-controller="mainCtrl as mainCtrl">
  <div ng-controller="firstCtrl as firstCtrl">
    <div ng-controller="secondCtrl as secondCtrl">
      {{secondCtrl.myLesson}}
    </div>
  </div>
</div>

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

secondCtrl as secondCtrl

как угодно. Как мы видим Lesson выводится в браузере. Теперь у нас нет проблем с пониманием из какого контроллера вызвалась переменная. Она не может находиться ни в firstCtrl, ни в mainCtrl.

Давайте скопируем этот код в другие контроллеры

var app = angular.module('app', []);

app.controller('mainCtrl', function () {
    this.myLesson = 'MainLesson';
});

app.controller('firstCtrl', function () {
    this.myLesson = 'FirstLesson';
});

app.controller('secondCtrl', function () {
    this.myLesson = 'SecondLesson';
});

Если мы хотим вывести myLesson из firstCtrl, то мы должны написать

{{firstCtrl.myLesson}}

Если же мы хотим вывести переменную из mainCtrl, то тогда пишем

{{mainCtrl.myLesson}}

Как мы видим, весь синтаксис, который нам нужно написать для того, чтобы controller as синтаксис работал это

имя-контроллер as имя-которые-мы-хотим-использовать

и в контроллере использовать this. В этом случае мы можем не использовать $scope вообще.

Давайте попробуем добавить какую-нибудь функцию, чтобы было видно как это выглядит.

<div ng-controller="mainCtrl as mainCtrl">
  <div ng-controller="firstCtrl as firstCtrl">
    <div ng-controller="secondCtrl as secondCtrl">
      {{secondCtrl.myLesson}}
      <button ng-click='mainCtrl.addLesson()'>Add lesson</button>
    </div>
  </div>
</div>

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

app.controller('mainCtrl', function () {
    this.myLesson = 'MainLesson';

    this.addLesson = function () {
        console.log('addLesson');
    }
});

Как мы видим, в браузере кнопка Add lesson работает и выводит сообщение в консоль.

Я во всех своих проектах применяю только controller as синтаксис, а $scope стараюсь использовать как можно реже.

Теперь давайте посмотрим как ангулар обрабатывает controller as синтаксис внутри себя. Давайте на примере mainCtrl заинджектим $scope и в конце контроллера в переменную this.mainCtrl запишем this.

app.controller('mainCtrl', function ($scope) {
    this.myLesson = 'MainLesson';

    this.addLesson = function () {
        console.log('addLesson');
    }

    $scope.mainCtrl = this;
});

Что это дает? Мы создали переменную mainCtrl, которая будет доступна в шаблоне. Если мы сейчас уберем controller as синтаксис для mainCtrl, то код продолжит работать без изменений, так как переменная mainCtrl у нас уже есть.

<div ng-controller="mainCtrl">
  <div ng-controller="firstCtrl as firstCtrl">
    <div ng-controller="secondCtrl as secondCtrl">
      {{mainCtrl.myLesson}}
      <button ng-click='mainCtrl.addLesson()'>Add lesson</button>
    </div>
  </div>
</div>

Только что мы с вами реализовали свой controller as синтаксис. Конечно лучше не использовать наш вариант, а использовать нативные методы ангулара так как это проще.

Только зарегистрированные пользователи могут оставлять комментарии.  Войдите, пожалуйста.