Синтаксис "контролер як" AngularJs - уточнення?


121

Я читав про новий синтаксис з angularJS щодоcontroller as xxx

Синтаксис InvoiceController as invoiceповідомляє Angular створити контролер і зберегти його в змінному рахунку в поточній області.

Візуалізація:

введіть тут опис зображення

Гаразд, так що я не буду мати параметр $scopeв моєму контролері, і код буде набагато чистішим в контролері.

Але

Мені доведеться вказати інший псевдонім у поданні

Так що до цих пір я міг зробити:

<input type="number" ng-model="qty"  />

....controller('InvoiceController', function($scope) {
   // do something with $scope.qty <--notice

І тепер я можу:

 <input type="number" ng-model="invoic.qty"  /> <-- notice 

  ....controller('InvoiceController', function() {
       // do something with  this.qty  <--notice

Питання

Яка мета цього зробити? видалення з одного місця та додавання в інше місце?

Я буду радий побачити, чого мені не вистачає.


8
Це відео це дуже добре пояснює. youtube.com/watch?v=tTihyXaz4Bo Я думаю, що він використовується для чистішого коду в HTML.
Фізер Хан

1
Чіткість. Мене не турбує використання $ range.x Vs this.x в контролері, але, на мій погляд, прив'язка до {{računice.x}} говорить мені більше, ніж просто {{x}} (imho). Крім того, мені цікаво, чи це стосується проблеми, про яку я чув у кутку, де у не-об’єктів у контролері є проблеми (тож Things.x було б добре, але x спричинить проблему).
Метт Робертс

1
@MattRoberts для вирішення останнього коментаря - проблема, що не стосується об'єкта, на яку ви посилаєтесь, не є кутовою проблемою настільки, як факт спадкування прототипічного javascript. Там гарне пояснення того , чому це відбувається в кутовий тут (поряд з тим, чому controller asфіксує його).
Russ Matney

Як я заміню $ range. $ Мовлення? у цьому новому випадку, оскільки це моє. Трансляція $, здається, не працює
Гаурав,

1
@Gaurav ви все ще можете ввести послугу $ range у свій контролер, навіть якщо ви використовуєте контролер як синтаксис для деяких властивостей, методів тощо.
Дерек

Відповіді:


163

Про це є кілька речей.

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

Пояснення, звідки береться властивість, теж дуже корисно.

Ви можете розміщувати контролери, і при читанні html-файлів чітко зрозуміло, куди приходить кожне майно.

Ви також можете уникнути деяких проблем із правилом крапок .

Наприклад, маючи два контролери, обидва з однаковою назвою 'name', Ви можете це зробити:

<body ng-controller="ParentCtrl">
    <input ng-model="name" /> {{name}}

    <div ng-controller="ChildCtrl">
        <input ng-model="name" /> {{name}} - {{$parent.name}}
    </div>
</body>

Ви можете змінювати і батьків, і дитину, в цьому немає проблем. Але вам потрібно скористатися, $parentщоб побачити ім'я батьків, тому що ви затінили його у своєму дочірньому контролері. У масовому коді html$parent може бути проблематично, ви не знаєте, звідки походить це ім'я.

З controller asвами можна робити:

<body ng-controller="ParentCtrl as parent">
    <input ng-model="parent.name" /> {{parent.name}}

    <div ng-controller="ChildCtrl as child">
      <input ng-model="child.name" /> {{child.name}} - {{parent.name}}
    </div>
</body>

Цей же приклад, але читати набагато зрозуміліше.


10
Також тут є непоганий приклад того, чому такий підхід для когось
Julian Hollmann

Це дуже корисно, коли ви гніздите контролери!
C_J

1
У мене виникають проблеми з подібною реалізацією вашої відповіді, дивіться stackoverflow.com/questions/38315538
Cody

Це також дозволяє використовувати клас es6 як контролер та посилатися на методи в HTML. foo() { ... }спосіб чистіший, ніж $scope.foo = function() { ... }.
Брайан Маккучон

17

Основна перевага controller asсинтаксису, яке я бачу, полягає в тому, що ви можете працювати з контролерами як класами, а не лише деякими функціями прикраси $ obseg, і скористатися спадщиною. Я часто стикаюся з ситуацією, коли є функціонал, який дуже схожий на ряд контролерів, і найбільш очевидно, що потрібно зробити - це створитиBaseController клас і успадкувати його.

Незважаючи на те, що є спадщина $ range, яка частково вирішує цю проблему, деякі люди вважають за краще писати код у більш OOP-манері, що, на мій погляд, полегшує код і міркувати про те.

Ось загадка для демонстрації: http://jsfiddle.net/HB7LU/5796/


1
Це повинно отримати більше результатів, оскільки Скрипка справді корисна
Мауг каже, що відновити Моніку

13

Я вважаю, що одна особлива перевага зрозуміла, коли ви вклали сфери застосування. Тепер буде абсолютно зрозуміло, з якої саме області посилається посилання на властивість.


7

Джерело

Різниця між створенням контролера за $scope objectдопомогою “controller as”синтаксису та vm та використання

Створення контролера за допомогою об'єкта $

Зазвичай ми створюємо контролер за допомогою об'єкта $ range, як показано в переліку нижче:

myApp.controller("AddController", function ($scope) {



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

        $scope.result = $scope.number1 + $scope.number2;

    }

});

Вище ми створюємо AddController з трьома змінними та однією поведінкою, використовуючи контролер об'єкта $ range та перегляд, які спілкуються один з одним. Об'єкт $ range використовується для передачі даних та поведінки погляду. Він склеює вигляд і контролер разом.

По суті об'єкт $ range виконує такі завдання:

  1. Передайте дані з контролера в режим перегляду

  2. Передайте поведінку від контролера перегляду

  3. Склеюємо контролер і переглядаємо разом

  4. Об'єкт $ range змінюється, коли змінюється подання, а представлення змінюється, коли змінюються властивості об'єкта $

Ми приєднуємо властивості до об’єкта $ $, щоб передавати дані та поведінку перегляду. Перш ніж використовувати об’єкт $ range в контролері, нам потрібно передати його у функції контролера як залежності.

Використання синтаксису «контролер як» та vm

Ми можемо переписати вищевказаний контролер, використовуючи контролер як синтаксис та змінну vm, як показано в переліку нижче:

myApp.controller("AddVMController", function () {

    var vm = this;

    vm.number1 = undefined;

    vm.number2=undefined;

    vm.result =undefined;

    vm.add = function () {

        vm.result = vm.number1 + vm.number2;

    }

});

По суті, ми призначаємо це до змінної vm, а потім додаємо до цього властивість та поведінку. У поданні ми можемо отримати доступ до AddVmController, використовуючи контролер як синтаксис. Це показано в списку нижче:

<div ng-controller="AddVMController as vm">

            <input ng-model="vm.number1" type="number" />

            <input ng-model="vm.number2" type="number" />

            <button class="btn btn-default" ng-click="vm.add()">Add</button>

            <h3>{{vm.result}}</h3>

  </div>

Звичайно, ми можемо використовувати інше ім'я, ніж "vm" в контролері як синтаксис. Під кришкою AngularJS створює об’єкт $ range і додає властивості та поведінку. Однак, використовуючи контролер як синтаксис, код є дуже чистим у контролері, і на екрані видно лише ім'я псевдоніма.

Ось кілька кроків для використання контролера як синтаксису:

  1. Створіть контролер без об’єкта $ range.

  2. Призначте це до локальної змінної. Я вважаю за краще ім'я змінної як vm, ви можете вибрати будь-яке ім'я на свій вибір.

  3. Приєднайте дані та поведінку до змінної vm.

  4. На поданні подайте псевдонім контролеру, використовуючи контролер як синтаксис.

  5. Ви можете надати будь-яке ім’я псевдоніму. Я вважаю за краще використовувати vm, якщо я не працюю з вкладеними контролерами.

При створенні контролера немає прямих переваг або недоліків використання об'єктного підходу $ range або контролера як синтаксису. Це виключно питання вибору, однак використання контролера як синтаксису робить код JavaScript контролера більш читабельним і запобігає будь-яким проблемам, пов’язаним із цим контекстом.

Вкладені контролери в об’єктному підході $

У нас є два контролери, як показано в переліку нижче:

myApp.controller("ParentController", function ($scope) {



    $scope.name = "DJ";

    $scope.age = 32;

});

myApp.controller("ChildController", function ($scope) {



    $scope.age = 22;

    $scope.country = "India";



});

Властивість "вік" знаходиться всередині обох контролерів, і на перегляді ці два контролери можуть бути вкладені, як показано в переліку нижче:

<div ng-controller="ParentController">



            <h2>Name :{{name}} </h2>

            <h3>Age:{{age}}</h3>



             <div ng-controller="ChildController">

                    <h2>Parent Name :{{name}} </h2>

                    <h3>Parent Age:{{$parent.age}}</h3>

                    <h3>Child Age:{{age}}</h3>

                    <h3>Country:{{country}}</h3>

             </div>

        </div>

Як бачите, для доступу до вікової властивості батьківського контролера ми використовуємо $ parent.age. Контекстне розділення тут не дуже зрозуміле. Але використовуючи контролер як синтаксис, ми можемо працювати з вкладеними контролерами в більш елегантний спосіб. Скажімо, у нас є контролери, як показано в переліку нижче:

myApp.controller("ParentVMController", function () {

    var vm = this;

    vm.name = "DJ";

    vm.age = 32;

});

myApp.controller("ChildVMController", function () {

    var vm = this;

    vm.age = 22;

    vm.country = "India";



});

На перегляді ці два контролери можна вкласти, як показано в переліку нижче:

<div ng-controller="ParentVMController as parent">



            <h2>Name :{{parent.name}} </h2>

            <h3>Age:{{parent.age}}</h3>



            <div ng-controller="ChildVMController as child">

                <h2>Parent Name :{{parent.name}} </h2>

                <h3>Parent Age:{{parent.age}}</h3>

                <h3>Child Age:{{child.age}}</h3>

                <h3>Country:{{child.country}}</h3>

            </div>

 </div>

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

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


4

Я вважаю, що головна перевага є більш інтуїтивно зрозумілим api, оскільки методи / властивості пов'язані безпосередньо з екземпляром контролера, а не об'єктом області. В основному, зі старим підходом, контролер стає просто прикрасою для створення об'єкта масштабу.

Ось додаткова інформація про це: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff


3

З того, що я читав, область "$" буде видалена в Angular 2.0, або, принаймні, як ми бачимо використання $ range. Можливо, було б добре почати використовувати контролер як вихід 2.0.

Відео посилання тут для більшого обговорення.

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