AngularJs "controller as" sintaks - klarifikasi?

121

Saya membaca tentang sintaks baru dari angularJS tentangcontroller as xxx

Sintaksnya InvoiceController as invoicememberitahu Angular untuk membuat instantiate controller dan menyimpannya dalam faktur variabel dalam lingkup saat ini.

Visualisasi:

masukkan deskripsi gambar di sini

Ok, jadi saya tidak akan memiliki parameter $scopedi pengontrol saya dan kode akan jauh lebih bersih di pengontrol.

Tapi

Saya harus menentukan alias lain dalam tampilan

Jadi Sampai sekarang saya bisa melakukan:

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

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

Dan sekarang saya bisa melakukan:

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

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

Pertanyaan

Apa tujuan melakukannya? menghapus dari satu tempat dan menambahkan ke tempat lain?

Saya akan senang melihat apa yang saya lewatkan.

Royi Namir
sumber
8
Video ini menjelaskannya dengan sangat baik. youtube.com/watch?v=tTihyXaz4Bo menurut saya ini digunakan untuk kode yang lebih bersih di HTML.
Fizer Khan
1
Kejelasan. Saya tidak repot-repot menggunakan $ scope.x Vs this.x di pengontrol, tetapi dalam pandangan saya, mengikat ke {{invoice.x}} memberi tahu saya lebih dari sekadar {{x}} (imho). Juga, saya bertanya-tanya apakah ini mengatasi masalah yang saya dengar di sudut di mana non-objek dalam pengontrol memiliki masalah (jadi things.x akan baik-baik saja, tetapi x akan menyebabkan masalah).
Matt Roberts
1
@MattRoberts untuk mengatasi komentar terakhir Anda - masalah non-objek yang Anda rujuk bukanlah masalah sudut sebanyak fakta warisan prototipe javascript. Ada penjelasan bagus mengapa hal itu terjadi dalam sudut di sini (bersama dengan mengapa controller asmemperbaikinya).
Russ Matney
Bagaimana cara mengganti $ scope. $ Broadcast? dalam kasus baru ini karena siaran saya ini. $ tampaknya tidak berfungsi
Gaurav
1
@Gaurav Anda masih dapat menyuntikkan layanan $ scope ke pengontrol Anda, bahkan jika Anda menggunakan pengontrol sebagai sintaks untuk beberapa properti, metode, dll.
Derek

Jawaban:

163

Ada beberapa hal tentang itu.

Beberapa orang tidak menyukai $scopesintaks (jangan tanya saya mengapa). Mereka mengatakan bahwa mereka bisa saja menggunakan this. Itulah salah satu tujuannya.

Memperjelas dari mana sebuah properti berasal juga sangat berguna.

Anda dapat menyarangkan pengontrol dan saat membaca html, cukup jelas di mana setiap properti berasal.

Anda juga dapat menghindari beberapa masalah aturan titik .

Misalnya, memiliki dua pengontrol, keduanya dengan nama 'nama' yang sama, Anda dapat melakukan ini:

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

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

Anda dapat memodifikasi orang tua dan anak, tidak masalah tentang itu. Tapi Anda perlu menggunakan $parentuntuk melihat nama orang tua, karena Anda membayangi pengontrol anak Anda. Dalam kode html masif $parentbisa jadi bermasalah, Anda tidak tahu dari mana nama itu berasal.

Dengan controller asAnda dapat melakukan:

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

Contoh yang sama, tetapi jauh lebih jelas untuk dibaca.

Jesus Rodriguez
sumber
10
Juga di sini adalah contoh yang cukup bagus mengapa pendekatan ini mungkin membingungkan bagi beberapa orang: stackoverflow.com/questions/25405543/…
Julian Hollmann
Ini sangat membantu saat Anda membuat pengontrol bersarang!
C_J
1
Saya mengalami masalah dengan implementasi serupa dari jawaban Anda, silakan lihat stackoverflow.com/questions/38315538
Cody
Ini juga memungkinkan Anda untuk menggunakan kelas es6 sebagai pengontrol Anda dan mereferensikan metode dalam HTML. foo() { ... }jauh lebih bersih dari $scope.foo = function() { ... }.
Brian McCutchon
17

Keuntungan utama dengan controller assintaks yang saya lihat adalah Anda dapat bekerja dengan pengontrol sebagai kelas, bukan hanya beberapa fungsi dekorasi ruang lingkup, dan memanfaatkan pewarisan. Saya sering mengalami situasi ketika ada fungsi yang sangat mirip dengan sejumlah pengontrol, dan hal yang paling jelas untuk dilakukan adalah membuat BaseControllerkelas dan mewarisinya.

Meskipun ada $ scope inheritence, yang sebagian memecahkan masalah ini, beberapa orang lebih suka menulis kode dengan cara yang lebih OOP, yang menurut saya, membuat kode lebih mudah untuk dipikirkan dan diuji.

Berikut biola untuk didemonstrasikan: http://jsfiddle.net/HB7LU/5796/

Roman Kolpak
sumber
1
Ini harus mendapatkan lebih banyak suara positif, karena Fiddle sangat membantu
Mawg mengatakan memulihkan Monica
13

Saya yakin satu keuntungan khusus jelas ketika Anda memiliki cakupan bersarang. Sekarang akan benar-benar jelas dari lingkup apa referensi properti berasal.

David M. Karr
sumber
7

Sumber

Perbedaan antara Membuat pengontrol menggunakan $scope objectdan Menggunakan “controller as”sintaks dan vm

Membuat pengontrol menggunakan objek $ scope

Biasanya kita membuat pengontrol menggunakan objek $ scope seperti yang ditunjukkan pada daftar di bawah ini:

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



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

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

    }

});

Di atas kita membuat AddController dengan tiga variabel dan satu perilaku, menggunakan pengontrol dan tampilan objek $ scope, yang berbicara satu sama lain. Objek $ scope digunakan untuk meneruskan data dan perilaku ke tampilan. Ini merekatkan tampilan dan pengontrol bersama.

Pada dasarnya objek $ scope melakukan tugas-tugas berikut:

  1. Meneruskan data dari pengontrol ke tampilan

  2. Meneruskan perilaku dari pengontrol ke tampilan

  3. Rekatkan pengontrol dan tampilan bersama

  4. Objek $ scope diubah saat tampilan berubah dan tampilan diubah ketika properti dari objek $ scope berubah

Kami melampirkan properti ke objek $ scope untuk meneruskan data dan perilaku ke tampilan. Sebelum menggunakan objek $ scope di controller, kita perlu meneruskannya ke fungsi controller sebagai dependensi.

Menggunakan sintaks "controller as" dan vm

Kita dapat menulis ulang pengontrol di atas menggunakan pengontrol sebagai sintaks dan variabel vm seperti yang ditunjukkan pada daftar di bawah ini:

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;

    }

});

Pada dasarnya kami menetapkan ini ke variabel vm dan kemudian melampirkan properti dan perilaku ke sana. Pada tampilan kita dapat mengakses AddVmController menggunakan pengontrol sebagai sintaks. Ini ditunjukkan dalam daftar di bawah ini:

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

Tentu saja kita bisa menggunakan nama lain selain "vm" di controller sebagai sintaks. Di bawah tenda, AngularJS membuat objek $ scope dan melampirkan properti dan perilaku. Namun dengan menggunakan pengontrol sebagai sintaks, kode di pengontrol sangat bersih dan hanya nama alias yang terlihat di tampilan.

Berikut beberapa langkah untuk menggunakan pengontrol sebagai sintaks:

  1. Buat pengontrol tanpa objek $ scope.

  2. Tetapkan ini ke variabel lokal. Saya lebih suka nama variabel sebagai vm, Anda dapat memilih nama pilihan Anda.

  3. Lampirkan data dan perilaku ke variabel vm.

  4. Pada tampilan, berikan alias ke pengontrol menggunakan pengontrol sebagai sintaks.

  5. Anda dapat memberikan nama apa pun ke alias. Saya lebih suka menggunakan vm kecuali saya tidak bekerja dengan pengontrol bersarang.

Dalam membuat pengontrol, tidak ada keuntungan atau kerugian langsung menggunakan pendekatan objek $ scope atau pengontrol sebagai sintaks. Ini murni masalah pilihan, namun, menggunakan pengontrol sebagai sintaks membuat kode JavaScript pengontrol lebih mudah dibaca dan mencegah masalah apa pun yang terkait dengan konteks ini.

Kontroler bersarang dalam pendekatan objek $ scope

Kami memiliki dua pengontrol seperti yang ditunjukkan pada daftar di bawah ini:

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



    $scope.name = "DJ";

    $scope.age = 32;

});

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



    $scope.age = 22;

    $scope.country = "India";



});

Properti "age" ada di dalam kedua pengontrol, dan pada tampilan kedua pengontrol ini bisa disarangkan seperti yang ditunjukkan dalam daftar di bawah ini:

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

Seperti yang Anda lihat, untuk mengakses properti age dari kontroler induk kita menggunakan $ parent.age. Pemisahan konteks tidak terlalu jelas di sini. Tetapi menggunakan pengontrol sebagai sintaks, kita dapat bekerja dengan pengontrol bersarang dengan cara yang lebih elegan. Katakanlah kita memiliki pengontrol seperti yang ditunjukkan pada daftar di bawah ini:

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



});

Pada tampilan, kedua pengontrol ini dapat disarangkan seperti yang ditunjukkan pada daftar di bawah ini:

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

Dalam pengontrol sebagai sintaks, kami memiliki kode yang lebih mudah dibaca dan properti induk dapat diakses menggunakan nama alias dari pengontrol induk daripada menggunakan sintaks $ induk.

Saya akan menyimpulkan posting ini dengan mengatakan bahwa itu murni pilihan Anda apakah Anda ingin menggunakan controller sebagai sintaks atau objek $ scope. Tidak ada keuntungan atau kerugian yang besar untuk keduanya, hanya saja pengontrol sebagai sintaks yang Anda kontrol pada konteksnya sedikit lebih mudah untuk dikerjakan, mengingat pemisahan yang jelas dalam pengontrol bersarang pada tampilan.

ShibinRagh
sumber
4

Saya menemukan keuntungan utama adalah api yang lebih intuitif karena metode / properti dikaitkan dengan contoh pengontrol secara langsung dan bukan objek lingkup. Pada dasarnya, dengan pendekatan lama, pengontrol hanya menjadi dekorasi untuk membangun objek lingkup.

Berikut beberapa info lebih lanjut tentang ini: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff

TGH
sumber
3

Dari apa yang saya baca, $ scope akan dihapus di Angular 2.0, atau setidaknya bagaimana kami melihat penggunaan $ scope. Mungkin baik untuk mulai menggunakan pengontrol saat rilis 2.0 semakin dekat.

Tautan video di sini untuk diskusi lebih lanjut tentang itu.

jason328
sumber