Haruskah saya menggunakan `this` atau` $ scope`?

251

Ada dua pola yang digunakan untuk mengakses fungsi pengontrol: thisdan $scope.

Yang mana yang harus saya gunakan dan kapan? Saya mengerti thisdiatur ke controller dan $scopemerupakan objek dalam rantai lingkup untuk dilihat. Tetapi dengan sintaks "Controller as Var" yang baru, Anda dapat dengan mudah menggunakan keduanya. Jadi yang saya tanyakan adalah apa yang terbaik dan apa arah untuk masa depan?

Contoh:

  1. Menggunakan this

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

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

Saya pribadi merasa this.namelebih mudah di mata dan lebih alami dibandingkan dengan pola OO Javascript lainnya.

Mohon saran?

SenseDeep
sumber
Menggunakan 'ini' tampaknya baru pada Google I / O 2013 m.youtube.com/watch?v=HCR7i5F5L8c Juga, periksa jawaban ini: stackoverflow.com/questions/11605917/…
AlanW
Apakah sintaks "UserCtrl as uCtrl" baru? Saya tidak melihatnya didokumentasikan pada halaman 1.0.6 atau 1.1.4 ngController.
Mark Rajcok
Oke, ini didokumentasikan pada halaman 1.1.5 ngController baru .
Mark Rajcok
1
Penjelasan terbaik untuk $ scope dan codetunnel.io/angularjs-controller-as-or-scope
Sai

Jawaban:

229

Keduanya memiliki kegunaannya. Pertama, beberapa sejarah ...

$ scope adalah teknik "klasik" sementara "controller as" jauh lebih baru (pada versi 1.2.0 secara resmi meskipun ia muncul dalam pra-rilis yang tidak stabil sebelum ini).

Keduanya bekerja dengan sangat baik dan satu-satunya jawaban yang salah adalah mencampurkannya di aplikasi yang sama tanpa alasan eksplisit. Terus terang, mencampurkannya akan berhasil, tetapi itu hanya akan menambah kebingungan. Jadi pilih satu dan gulingkan dengan itu. Yang paling penting adalah konsisten.

Yang mana? Itu tergantung kamu. Ada banyak lagi contoh di luar sana dari $ scope, tetapi "controller as" juga ikut ambil bagian. Apakah yang satu lebih baik dari yang lain? Itu bisa diperdebatkan. Jadi, bagaimana Anda memilih?

Kenyamanan

Saya lebih suka "controller as" karena saya suka menyembunyikan lingkup $ dan mengekspos anggota dari controller ke tampilan melalui objek perantara. Dengan mengatur ini. *, Saya dapat mengekspos apa yang ingin saya paparkan dari controller ke view. Anda dapat melakukannya dengan $ scope juga, saya hanya lebih suka menggunakan JavaScript standar untuk ini. Bahkan, saya kode seperti ini:

var vm = this;

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

return vm;

Ini terasa lebih bersih bagi saya dan memudahkan untuk melihat apa yang terpapar pada tampilan. Perhatikan saya beri nama variabel yang saya kembalikan "vm", yang merupakan singkatan dari viewmodel. Itu hanya konvensi saya.

Dengan $ scope saya bisa melakukan hal yang sama, jadi saya tidak menambahkan atau mengurangi tekniknya.

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

Jadi terserah Anda di sana.

Injeksi

Dengan $ scope saya perlu menyuntikkan $ scope ke controller. Saya tidak harus melakukan ini dengan controller, kecuali saya membutuhkannya untuk alasan lain (seperti $ broadcast atau jam tangan, meskipun saya mencoba untuk menghindari jam tangan di controller).

UPDATE Saya menulis posting ini tentang 2 pilihan: http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/

John Papa
sumber
4
Secara pribadi saya juga mengikuti pendekatan Anda menggunakan vm. Satu-satunya aroma kode yang saya ambil adalah ketika Anda perlu berinteraksi secara khusus dengan $ scope, mis. Berlangganan atau menyiarkan acara, mengakses variabel validasi formulir di dalam controller Anda dll. Ini mengarah ke lingkungan yang agak campur aduk di mana Anda masih perlu menyuntikkan $ scope meskipun Anda menggunakan pengontrol sebagai fitur.
Beyers
9
Baik. $ scope masih digunakan untuk kasus itu, tetapi lebih digunakan sebagai layanan. Ketika kami menyuntikkan layanan sudut ($ scope, $ q, dll) mereka menyediakan beberapa fitur yang kami butuhkan. $ scope memungkinkan kita untuk menonton, menerapkan, menggunakan pesan dan juga mengikat data. Dan bahkan ketika menggunakan controller sebagai, $ scope masih digunakan, itu hanya diabstraksikan
John Papa
1
var vm = this;apakah Anda perlu menyebutnya 'vm' dalam tampilan juga? 'controller as vm'. Apakah mereka harus sama?
Javid
2
@JohnPapa - Mengapa templat SideWaffle tidak "mengembalikan vm;" saat menggunakan Controller As?
Kevin
2
@Kevin Controllers secara efektif bertindak sebagai Ctor dan dengan demikian mengembalikan "ini".
John Papa
68

$scopesedang dihapus di Angular 2.0. Dengan demikian, menggunakan thisakan menjadi pendekatan yang orang lain ingin ikuti karena tanggal rilis Angular 2.0 semakin dekat.

jason328
sumber
40

Pendapat saya adalah bahwa 'ini' di javascript memiliki cukup banyak masalah sendiri, dan menambahkan arti / penggunaan lain untuk itu bukan ide yang baik.

Saya akan menggunakan $ scope, demi kejelasan.

MEMPERBARUI

Sekarang ada sintaks 'controller as', dibahas di sini . Saya bukan penggemar, tapi sekarang ini AngularJS yang lebih 'resmi', konstruksi ini patut mendapat perhatian.

Roy Truelove
sumber
10
Saya pikir kita pertama-tama perlu memahami sintaks "UserCtrl as uCtrl" yang baru sebelum kita dapat mengatakan mana yang menurut kami lebih baik.
Mark Rajcok
Re 'UserCtrl as uCtrl', saya setuju, ini perlu dipahami. Saya pikir itu ide yang buruk, karena sebagian besar alasan yang sama dengan argumen yang dibuat di sini: groups.google.com/forum/#!topic/angular/84selECbp1I
Roy Truelove
4
Jika Anda terbiasa dengan oop di JS, itu sangat masuk akal. Kontroler adalah kelas, dan sudut menggunakan operator baru setiap kali controller dibuat. Anda dipersilakan untuk tidak menyukainya, tetapi menyatakan ada masalah dengan menggunakan 'ini' adalah menyesatkan. Ini adalah kasus penggunaan yang dapat diterima untuk 'ini'.
MJ
$ scope tidak menambah kejelasan. Bahkan bisa sangat sulit untuk mengetahui apa yang terjadi dalam tampilan ketika menggunakan $ scope dan Anda memiliki ruang bersarang. Kontroler sebagai sintaks bersama dengan menggunakan ini menambah kejelasan. Dalam tampilan itu bagus dan jelas dari mana ruang lingkup pengendali metode atau properti berasal.
ddelrio1986
1
Saya setuju dengan @ddelrio1986. Baru saja mengalami masalah dengan tab bootstrap dan agular dengan menggunakan var vm = $ scope. Tab memiliki cakupannya sendiri dan jadi Anda tidak dapat menggunakan ini seperti yang Anda harapkan tetapi dengan var vm = ini, semuanya berfungsi seperti yang diharapkan.
user441521
11

Saya pikir Controller As lebih baik karena memungkinkan untuk lebih mudah bersarang lingkup seperti yang dijelaskan oleh Motto Todd di sini:

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

Juga, itu akan memastikan bahwa Anda selalu memiliki setidaknya satu. dalam ekspresi mengikat Anda yang memaksa Anda untuk mengikuti jangan mengikat primitif rekomendasi .

Plus Anda dapat memisahkan dari lingkup yang akan hilang dalam 2.0.

Ryan Vice
sumber
7

Dokumentasi Angular secara eksplisit memberi tahu Anda bahwa penggunaan thisdisarankan. Itu, selain fakta yang $scopesedang dihapus adalah alasan yang cukup bagi saya untuk tidak pernah menggunakan $scope.

tjespe
sumber
4

"$ scope jason328 sedang dihapus dalam Angular 2.0" sepertinya alasan yang bagus untuk saya. Dan saya menemukan alasan lain untuk membantu saya membuat pilihan: thislebih mudah dibaca - ketika saya melihat fooCtrl.bardalam HTML, saya langsung tahu di mana menemukan definisi bar.

Pembaruan: tidak lama setelah beralih ke thissolusi, saya mulai ketinggalan $scopecara yang kurang perlu mengetik

ZZY
sumber
2

Saya lebih suka kombinasi.

Log console.log sederhana dari $ scope dan 'this' setelah mengisinya dengan beberapa data tiruan akan menunjukkan itu.

$ scope memungkinkan akses ke bagian sampul pengendali, misalnya:

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

** Properti dan metode dengan $$ tidak disarankan untuk dipusingkan oleh tim Angular, tetapi $ dapat menjadi game yang aman untuk melakukan hal-hal keren dengan $ parent dan $ id.

'ini' langsung ke intinya, melampirkan data dan fungsi 2 arah terikat. Anda hanya akan melihat apa yang Anda lampirkan:

foo: 'bar';

Jadi mengapa saya lebih suka kombinasi?

Dalam aplikasi bersarang ui-router, saya dapat mengakses controller utama, mengatur dan memanggil nilai-nilai universal dan fungsi di dalam controller anak:

Di Pengontrol Utama:

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

Dalam Kontrol Anak:

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

Sekarang, Anda dapat mengakses orang tua dari dalam anak dan anak dari orang tua!

Craig O. Curtis
sumber
1

Keduanya berfungsi, tetapi jika Anda menerapkan hal-hal yang sesuai untuk lingkup ke $ lingkup, dan jika Anda menerapkan hal-hal yang sesuai untuk pengontrol ke pengontrol, kode Anda akan mudah dipelihara. Untuk orang-orang yang mengatakan "Ugh, gunakan saja ruang lingkup, lupakan Pengontrol ini sebagai sintaksis" ... Ini mungkin bekerja sama tetapi saya bertanya-tanya bagaimana Anda akan dapat mempertahankan aplikasi besar tanpa kehilangan jejak.

Nick Manning
sumber