"This" veya "$ scope" kullanmalı mıyım?


251

Denetleyici işlevlerine erişmek için kullanılan iki desen vardır: thisve $scope.

Hangisini ve ne zaman kullanmalıyım? Anladım thisdenetleyiciye ayarlanmış ve $scopegörünümler için kapsam zincirinde bir nesne. Ancak yeni "Controller as Var" sözdizimi ile kolayca kullanabilirsiniz. Sorduğum şey, en iyi olanın ve geleceğin yönü nedir?

Misal:

  1. kullanma this

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

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

Şahsen this.namediğer Javascript OO modellerine kıyasla göze daha kolay ve daha doğal buluyorum .

Öneri lütfen?


Google I / O 2013'ten itibaren 'this' kullanmak yeni gibi görünüyor m.youtube.com/watch?v=HCR7i5F5L8c Ayrıca, bu yanıtı da kontrol edin: stackoverflow.com/questions/11605917/…
AlanW

"UserCtrl as uCtrl" sözdizimi yeni mi? 1.0.6 veya 1.1.4 ng Denetleyici sayfalarında belgelendiğini görmüyorum.
Mark Rajcok


Yanıtlar:


229

Her ikisinin de kullanımları vardır. İlk olarak, biraz tarih ...

$ scope "classic" tekniğidir, "controller as" ise çok daha yenidir (1.2.0 sürümünden itibaren resmen bundan önceki kararsız sürümlerde görünmesine rağmen).

Her ikisi de mükemmel çalışır ve tek yanlış cevap, onları açık bir neden olmadan aynı uygulamada karıştırmaktır. Açıkçası, onları karıştırmak işe yarayacak, ama sadece karışıklığa katkıda bulunacak. Öyleyse birini seç ve onunla yuvarlan. En önemli şey tutarlı olmaktır.

Hangisi? Bu sana bağlı. Orada $ scope daha birçok örnek var, ama "denetleyici as" buhar da alıyor. Biri diğerinden daha iyi mi? Bu tartışılır. Yani, nasıl seçiyorsun?

Konfor

Ben "denetleyici olarak" tercih çünkü $ kapsam gizleme ve bir denetleyici nesnesi aracılığıyla denetleyiciden görünüme üyeleri maruz seviyorum. Bunu ayarlayarak. *, Denetleyiciden görünüme göstermek istediğim şeyi gösterebilirim. Bunu $ scope ile de yapabilirsiniz, sadece bunun için standart JavaScript kullanmayı tercih ederim. Aslında, ben böyle kod:

var vm = this;

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

return vm;

Bu bana daha temiz geliyor ve görünüme neyin maruz kaldığını görmeyi kolaylaştırıyor. Uyarı "vm" döndürdüğüm değişkeni adlandırıyorum, bu da viewmodel anlamına gelir. Bu sadece benim konvansiyonum.

$ Kapsamı ile ben de aynı şeyleri yapabilirim, bu yüzden tekniği ekleme veya küçültme değil.

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

Yani orada size kalmış.

Enjeksiyon

$ Scope ile denetleyiciye $ scope enjekte etmem gerekiyor. Bunu başka bir nedenden dolayı ($ yayın veya saatler gibi, kontrolördeki saatlerden kaçınmaya çalışıyorum) sürece kontrolörle yapmak zorunda değilim.

GÜNCELLEME Bu yazıyı 2 seçenek hakkında yazdım: http://www.johnpapa.net/do-you-like-your-angular-controllers-with-or-without-sugar/


4
Şahsen ben de vm kullanarak yaklaşımınızı takip ediyorum. Aldığım tek kod kokusu, özellikle $ scope ile etkileşime girmeniz gerektiğinde, örneğin olaylara abone olma veya yayın yapma, denetleyicinizin içindeki form doğrulama değişkenlerine erişme vb. Bu, hala $ scope enjekte etmeniz gereken biraz karışık bir ortama yol açar. denetleyiciyi özellik olarak kullanmanıza rağmen.
Beyers

9
Sağ. $ scope hala bu durumda kullanılır, ancak daha çok hizmet olarak kullanılır. Açısal hizmetleri ($ kapsam, $ q, vb.) Enjekte ettiğimizde, ihtiyacımız olan bazı özellikleri sağlarlar. $ scope, veri bağlamanın yanı sıra mesajları izlememize, uygulamamıza, kullanmamıza olanak tanır. Ve denetleyici olarak kullanılırken bile, $ scope hala kullanılıyor, sadece soyutlandı
John Papa

1
var vm = this;görünümde de 'vm' demeniz mi gerekiyor? 'denetleyici vm olarak'. Aynı olmaları gerekiyor mu?
Javid

2
@JohnPapa - Neden SideWaffle şablonları "return vm;" Controller As kullanırken?
Kevin

2
@Kevin Denetleyicileri etkin bir şekilde bir Ctor gibi davranırlar ve bu nedenle zaten "bunu" döndürürler.
John Papa

68

$scopeAçısal 2.0'da kaldırılıyor. Bu nedenle, thisAngular 2.0'ın piyasaya sürülme tarihi yaklaştıkça, başkalarının takip etmek istediği bir yaklaşım kullanmak olacaktır.


40

Benim düşüncem, javascript'teki `` bu '' nun kendi başına yeterli sorunları olduğu ve bunun için başka bir anlam / kullanım eklemenin iyi bir fikir olmadığıdır.

Açıklık uğruna $ kapsamı kullanırdım.

GÜNCELLEME

Şimdi burada tartışılan 'denetleyici olarak' sözdizimi var . Ben bir hayran değilim, ama şimdi daha 'resmi' bir AngularJS yapısı olduğu için biraz ilgiyi hak ediyor.


10
Sanırım hangisinin daha iyi olduğunu düşündüğümüzü söyleyebilmemiz için önce yeni "UserCtrl uCtrl olarak" sözdizimini anlamamız gerekiyor.
Mark Rajcok

'UserCtrl uCtrl' olarak, katılıyorum, bunun anlaşılması gerekiyor. Sanırım burada yapılan argümanlarla aynı nedenlerden dolayı kötü bir fikir: groups.google.com/forum/#!topic/angular/84selECbp1I
Roy Truelove

4
JS'de oop hakkında bilginiz varsa, bu çok mantıklıdır. Denetleyici bir sınıftır ve açısal, her denetleyici oluşturulduğunda yeni işleci kullanır. Beğenmekten memnuniyet duyarız, ancak 'bu' kullanımıyla ilgili sorunlar olduğunu belirtmek yanıltıcıdır. 'Bu' için kabul edilebilir bir kullanım durumudur.
MJ

$ scope netliğe hiçbir şey katmaz. Aslında, $ scope'u kullanırken görünümde neler olduğunu bilmek çok zor olabilir ve kapsamları iç içe geçirmişsinizdir. Sözdizimi olarak kontrolör, bununla birlikte çok daha fazla netlik katar. Görünümde, bir yöntemin veya özelliğin hangi denetleyicinin kapsamından kaynaklandığı gayet güzel ve açıktır.
ddelrio1986

1
@ Ddelrio1986 ile hemfikirim. Sadece bootstrap sekmeleri ile ilgili bir sorun vardı ve var vm = $ scope kullanarak açısal. Sekmelerin kendi kapsamları vardır ve bu nedenle bunu beklediğiniz gibi kullanamazsınız, ancak var vm = this ile işler beklendiği gibi çalışır.
user441521


7

Açısal belgeler açıkça kullanmanın thisönerildiğini belirtir . Bu, $scopekaldırılmakta olan gerçeğe ek olarak, asla kullanmam için yeterli neden $scope.


4

jason328'in "Açısal 2.0'da $ kapsamı kaldırılıyor" benim için iyi bir neden. Ve seçim yapmama yardımcı olmak için başka bir neden buldum: thisdaha okunabilir - fooCtrl.barHTML'de gördüğümde, tanımını nerede bulacağımı hemen biliyorum bar.

Güncellemeler: thisçözüme geçtikten kısa bir süre sonra , $scopedaha az yazmayı gerektiren yolu kaçırmaya başladım


2

Bir kombinasyonu tercih ederim.

Basit bir console.log $ scope ve 'bu' onları bazı sahte verilerle doldurduktan sonra size bunu gösterecektir.

$ scope, bir denetleyicinin kapak bölümlerine erişim sağlar, örneğin:

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

** $$ ile özellikler ve yöntemlerin Açısal ekip tarafından uğraşması tavsiye edilmez, ancak $ $ ebeveyn ve $ id ile harika şeyler yapmak için güvenli bir oyun olabilir.

'this' doğrudan noktaya gelir ve 2 yönlü veri ve fonksiyonlar ekler. Yalnızca ne eklediğinizi göreceksiniz:

foo: 'bar';

Öyleyse neden bir kombinasyonu tercih ediyorum?

Ui-router iç içe uygulamalarda, ana denetleyiciye erişebilir, alt denetleyicideki evrensel değerleri ve işlevleri ayarlayabilir ve çağırabilirim:

Ana Denetleyicide:

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

Çocuk Denetleyicide:

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

Artık ebeveyne çocuktan ve çocuğa ebeveynden erişebilirsiniz!


1

Her ikisi de çalışır, ancak kapsam için uygun olanları $ scope'a uygularsanız ve denetleyiciye uygun olanları denetleyiciye uygularsanız, kodunuzun bakımı kolay olacaktır. "Ugh sadece kapsamı bu denetleyiciyi sözdizimi olarak unut" diyenlere ... Aynı şekilde çalışabilir, ancak bir şeyleri kaybetmeden büyük bir uygulamayı nasıl koruyabileceğinizi merak ediyorum.

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.