Soru AngularJS - Neden “Controller vm” kullanıyorsunuz?


Tüm bu haftasonu, bir ana denetleyicinin işlevinin neden bir çocuk denetleyicisi tarafından tanınmamasını anlamaktan çok sıkıntı çekiyordum.

Çok geçmeden kontrol cihazımın vm olması sebebi olduğunu fark ettim:

 <div data-ng-controller="ParentCtrl as vm">
   <div data-ng-controller="Child1 as vm"></div>
   <div data-ng-controller="Child2 as vm"></div>
 </div>

Tabii ki, her ikisi de çocuk1 ne 2'nin ParentCtrl'deki işlevleri görmeyeceği ve bunun yerine vm olmadan çalışmanın önceki modelini kullandım ve bunun yerine $ kapsamı vardı, her şey iyi olurdu.

Bu yüzden benim sorum şu: "vm" yöntemini kullanmak için kimseye ne yararı var, ve kullanmamanın bir üstünlüğü varsa, ParentCtrl yayma kipinde bir çağrı fonksiyonu nasıl çağrılabilir?

Teşekkür ederim


25
2018-03-09 17:38


Menşei


Daha önce "as" sözdizimini gördüm, ama hiç kullanmadım. Görünümlerimin doğrudan denetleyiciye / ada göre erişmesini sevmiyorum. Ayrıca, kapsülleme perspektifinden Child1 veya Child2, ana denetleyici hakkında hiçbir şey bilmemelidir; ve bu nedenle ana kontrolördeki fonksiyonları çağırmamalıdır. Denetleyiciler arasındaki iletişim, paylaşılan bir hizmeti değiştirerek olmalıdır; ya da bir etkinlik dağıtıcısı olarak yaymayı kullanarak. - JeffryHouser
Reboog, eğer doğru bir şekilde anlıyorsam, "vm" yi kullanmamanız, fakat yine de $ kapsamına güvenmemeniz ve Veli'nin işlevinin çocuklar tarafından kapsamdan erişilebildiği gerçeğinden bağımsız olarak yayma kullanmanızın doğru olduğuna ? - Mike Jones
Evet, bu benim görüşüm ve benim aldığım yaklaşım. Henüz anlamadığım sorunlar olabilir, ancak henüz herhangi bir sınırlamaya / probleme rastlamadım. - JeffryHouser
Bu egghead.io videosu 'denetleyici' sözdizimini kullanmanın bazı nedenlerini açıklar. Bunu sorduğun için teşekkürler, o videodan bir şeyler öğrendim;) - Sunil D.


Cevaplar:


Denetleyiciyi sözdizimi olarak kullanmanın bir avantajı, denetleyicilerinizi, $ kapsamı yerine doğrudan örneklenen nesneden doğrudan etkilenen özelliklere ve işlevlere sahip basit bir javascript yapıcı işlevi olarak tanımlamanıza olanak sağlamasıdır.

Örneğin:

function MyController() {

    var ctl = this;

    ctl.message = 'You have not clicked anything yet.';

    ctl.onClick = function() {
        ctl.message = 'You clicked something.';
    };

    return ctl;
}

...

myModule.controller('MyController', MyController);

...

<div ng-controller="MyController as vm">
    <span>{{vm.message}}</span>
    <button ng-click="vm.onClick()">Click Me</button>
</div>

Düz eski javascript olan bir denetleyiciyi bile açısal olarak bağlı olmaksızın kullanabileceğimize dikkat edin. $ Kapsamı veya diğer hizmetler gibi ek bağımlılıklara gereksinim duyduğunuz senaryolar için, bunları kurucunuza kolayca aktarabilirsiniz, ancak bu desen $ kapsamınızda daha az karmaşayı teşvik eder ve değişkenler doğrudan ayarlandığında değişken gizleme sorununu çözer. kapsamı

Nihayetinde gerçekten bir tercih meselesi haline geliyor, ama benim için her şeyi doğrudan kapsam üzerinde tanımlamaktan ve denetleyicileri mümkün olduğunca eski bir javascript nesnesi gibi ele almaktan hoşlanmamayı seviyorum.

İşte denetleyicinin kullanımıyla ilgili mükemmel bir makale: http://www.johnpapa.net/angularjss-controller-as-and-the-vm-variable/


24
2017-08-04 13:26





Denetleyiciyi vm sözdizimi olarak kullandım, ama son zamanlarda ondan uzaklaşıyorum. Kapsam yalıtımı kullanan iç içe geçmiş yönergelerle karmaşık sayfalar oluşturduğumda, geleneksel $ kapsam yaklaşımının çalışmak çok daha kolay olduğunu buluyorum.

Senin sorunun bir süreliğine merak ettim. Görebildiğim tek gerçek değer, bir sayfada iç içe geçmiş denetleyicileri kullandığınızda, her bir kapsam için semantik referans alabilmeniz, böylece işaretlemenizin okunması biraz daha kolaylaşır. Yani, örneğin:

<div ng-controller="CustomersCtrl as customers">
    <div ng-controller="OrdersCtrl as orders">
         <p>Showing{{customers.model.length}} customers with a total of {{orders.model.length}} orders</p>
    </div>
</div>

Bunun dışında, değeri gerçekten görmüyorum ve yaptığım gibi direktiflerle iç içe geçmeyi tercih ederseniz, değer hızla imho'yu geçersiz kılar.


15
2018-03-14 10:06





Bu örnekle yaşadığınız şey özellikle denetleyicinin sözdizimi olarak kullanılmasından değil; bunun yerine, adlandırma nedeniyle ebeveyni gizleyen iç içe nesnelerinizden kaynaklanır.

İsteğe bağlı denetleyici, CoffeeScript veya TypeScript gibi JavaScript'le derlenen diğer dillerle yoğun şekilde çalışırken oldukça kullanışlıdır. Ayrıca, $ kapsam enjeksiyonuna ihtiyaç duymadığından, açısal olmayan bileşenlerle değiştirilebilen çok daha hafif kontrolörler oluşturmanıza da olanak tanır. Bu sadece bir alternatif sözdizimidir, ancak isterseniz kapsamı hala kullanabilirsiniz.

Buradaki asıl soru, denetleyicinin sözdizimi olarak yazdığı kişilerin "vm" yi kullanmaya karar vermesidir. Teknik olarak, sözdizimi bir MVVM stili kodlama deneyimi sağlamak için tasarlanmıştır ve bu nedenle "vm olarak" kullanılması mantıklı olabilir, ancak bu sizin gördüğünüz sorunu ortaya çıkarır. Ebeveyn denetleyiciniz adında bir nesnedir vmve çocuğunuzun nesnesi de adlandırılır vmbu yüzden çocuk nesnesi gizleme ana nesne görünümden. Bunun yerine, nesnelerinizi farklı şekilde adlandırırsanız, alt nesnenin ana nesneye erişme sorunu olmaz ve aslında çalıştığınız mülke nesnel olan kodda çok açık bir şekilde görülecektir.


8
2018-03-14 12:45





Bence en önemli avantajlardan biri, otomatik olarak bir . senin bağlarında. Çünkü Angular'de başparmak kuralı yoksa . Bağlanmalarınızda kendinizi ayağınıza vurabilirsiniz.

Bunu sahip olduğunu düşünün:

<input ng-model="foo" />

Bu amaçlandığı gibi çalışmayabilir. Öte yandan, eğer SomeController as vm sözdizimi otomatik olarak bununla sona erer:

<input ng-model="vm.foo" />

Bu, sizi beklendiği gibi çalışmayan veri bağlamasındaki olası sorunlardan koruyacaktır.

Bunun arkasındaki nedenler prototip kalıtım yolunda JavaScript'in içinde yer alır ve burada çok ayrıntılı olarak açıklanmıştır: AngularJS'de kapsam prototip / prototipik mirasın nüansları nelerdir?


5
2018-03-14 12:22





Anladığım kadarıyla, "denetleyici olarak vm" sözdizimini kullanmanın ana nedeni, angularjs'deki denetleyiciler aslında model olarak çalışır (verileri depolar ve davranışları sağlar) veya modelleri görüntüler (verileri html'ye sunar).

Çoğu durumda iyi çalıştı, ama karşılaştığım bir ana düşüş ana denetleyicideki verilere alt denetleyiciden erişmek zorve olası çözüm (Ebeveyn denetleyicisini, tüm denetleyicileri vm 'notasyonu olarak kullanan alt denetleyicide alın.) zarif değil.


1
2017-10-02 14:11