AngularJs "denetleyici olarak" sözdizimi - açıklama?


121

Ben yeni sözdizimi hakkında okumak ilişkin angularjs gelencontroller as xxx

Sözdizimi InvoiceController as invoice, Angular'a denetleyiciyi somutlaştırmasını ve geçerli kapsamdaki değişken faturaya kaydetmesini söyler.

Görselleştirme:

görüntü açıklamasını buraya girin

Tamam, bu yüzden $scopedenetleyicimde parametre olmayacak ve kod denetleyicide çok daha temiz olacak.

Fakat

Görünümde başka bir takma ad belirtmem gerekecek

Bu yüzden şimdiye kadar yapabilirim:

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

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

Ve şimdi yapabilirim:

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

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

Soru

Bunu yapmanın amacı nedir? bir yerden kaldırıp başka bir yere eklemek?

Neyi kaçırdığımı görmekten memnun olacağım.


8
Bu video bunu çok iyi açıklıyor. youtube.com/watch?v=tTihyXaz4Bo HTML'de daha temiz kod için kullanıldığını düşünüyorum.
Fizer Khan

1
Açıklık. Denetleyicide $cope.x Vs this.x'i kullanmak beni rahatsız etmiyor, ancak benim görüşüme göre {{invoice.x}} için bağlanmak bana {{x}} (imho) 'dan daha fazlasını anlatıyor. Ayrıca, bunun, denetleyicideki nesnelerin sorunlarının olduğu açısal olarak duyduğum bir sorunu ele alıp almadığını merak ediyorum (bu nedenle, things.x iyi olur, ancak x bir soruna neden olur).
Matt Roberts

1
Son yorumunuzu ele almak için @MattRoberts - başvurduğunuz nesne olmayan sorun, javascript prototip kalıtım gerçeği kadar açısal bir sorun değildir. O açısal olur neden iyi bir açıklaması var burada (neden birlikte controller asdüzeltmeleri o).
Russ Matney

$ Kapsam. $ Yayınını nasıl değiştireceğim? bu yeni durumda, çünkü bu. $
Gaurav

1
@Gaurav, denetleyiciyi bazı özellikler, yöntemler vb. İçin sözdizimi olarak kullansanız bile, $ kapsam hizmetini hala denetleyicinize enjekte edebilirsiniz.
Derek

Yanıtlar:


163

Bununla ilgili birkaç şey var.

Bazı insanlar $scopesözdizimini sevmez (nedenini sormayın). Sadece kullanabileceklerini söylüyorlar this. Hedeflerden biri buydu.

Bir mülkün nereden geldiğini netleştirmek de gerçekten yararlıdır.

Denetleyicileri yerleştirebilirsiniz ve html'yi okurken her özelliğin nereden geldiği oldukça açıktır.

Ayrıca bazı nokta kuralı sorunlarından da kaçınabilirsiniz .

Örneğin, her ikisi de aynı ada sahip iki denetleyiciye sahip olmak, Bunu yapabilirsiniz:

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

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

Hem ebeveyni hem de çocuğu değiştirebilirsiniz, bu konuda sorun yok. Ancak $parentebeveynin adını görmek için kullanmanız gerekir , çünkü onu alt denetleyicinizde gölgelediniz. Büyük html kodunda $parentsorunlu olabilir, bu adın nereden geldiğini bilmiyorsunuz.

İle controller asYapabileceğiniz:

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

Aynı örnek, ancak okumak çok daha net.


10
Ayrıca, bu yaklaşımın bazıları için neden kafa karıştırıcı olabileceğine dair oldukça güzel bir örnek: stackoverflow.com/questions/25405543/…
Julian Hollmann

Bu, denetleyicileri yerleştirirken çok yararlıdır!
C_J

1
Cevabınızın benzer bir şekilde uygulanmasında sorun yaşıyorum, lütfen stackoverflow.com/questions/38315538
Cody

Bu ayrıca, denetleyiciniz olarak bir es6 sınıfını kullanmanıza ve HTML'deki yöntemlere başvurmanıza olanak tanır. foo() { ... }çok daha temiz $scope.foo = function() { ... }.
Brian McCutchon

17

Söz controller asdiziminin ana avantajı, denetleyicilerle yalnızca bazı $ kapsam dekorasyon işlevleri değil, sınıflar olarak çalışabilmeniz ve kalıtımdan yararlanabilmenizdir. Çoğu zaman, bir dizi denetleyiciye çok benzeyen bir işlevsellik olduğunda bir durumla karşılaşırım ve yapılacak en bariz şey, bir BaseControllersınıf oluşturmak ve ondan miras almaktır.

Bu sorunu kısmen çözen $ kapsam kalıtımı olsa da, bazı insanlar kodu daha OOP tarzında yazmayı tercih ediyor, bu da bana göre kodu akıl yürütmeyi ve test etmeyi kolaylaştırıyor.

İşte gösterilecek bir keman: http://jsfiddle.net/HB7LU/5796/


1
Fiddle gerçekten yardımcı olduğu için bu daha fazla olumlu oy almalı
Mawg, Monica'nın

13

İç içe geçmiş kapsamlara sahip olduğunuzda belirli bir avantajın açık olduğuna inanıyorum. Artık bir özellik referansının tam olarak hangi kapsamdan geldiği tamamen netleşecek.


7

Kaynak

Sözdizimi ve vm $scope objectkullanarak denetleyici oluşturma ve kullanma arasındaki fark“controller as”

$ Kapsam nesnesini kullanarak bir denetleyici oluşturma

Genellikle, aşağıdaki listede gösterildiği gibi $ kapsam nesnesini kullanarak bir denetleyici oluştururuz:

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



    $scope.number1;

    $scope.number2;

    $scope.result;

    $scope.add = function () {

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

    }

});

Yukarıda, birbiriyle konuşan $ kapsam nesne denetleyicisini ve görünümünü kullanarak üç değişken ve bir davranışla AddController oluşturuyoruz. $ Kapsam nesnesi, verileri ve davranışı görünüme geçirmek için kullanılır. Görüntüyü ve denetleyiciyi birbirine yapıştırır.

Esasen $ kapsam nesnesi aşağıdaki görevleri gerçekleştirir:

  1. Denetleyiciden görünüme veri aktarın

  2. Denetleyiciden görünüme davranış geçirme

  3. Denetleyiciyi ve görünümü birbirine yapıştırır

  4. $ Kapsam nesnesi, bir görünüm değiştiğinde ve $ kapsam nesnesinin özellikleri değiştiğinde bir görünüm değiştirildiğinde değiştirilir

Verileri ve davranışı görünüme iletmek için bir $ kapsam nesnesine özellikler ekliyoruz. Denetleyicide $ kapsam nesnesini kullanmadan önce, onu denetleyici işlevine bağımlılık olarak geçirmemiz gerekir.

"Controller as" sözdizimi ve vm'yi kullanma

Denetleyiciyi sözdizimi olarak ve vm değişkenini aşağıdaki listede gösterildiği gibi kullanarak yukarıdaki denetleyiciyi yeniden yazabiliriz:

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;

    }

});

Esasen bunu bir değişken vm'ye atıyoruz ve sonra buna bir özellik ve davranış ekliyoruz. Görünümde, denetleyiciyi sözdizimi olarak kullanarak AddVmController'a erişebiliriz. Bu, aşağıdaki listede gösterilmektedir:

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

Elbette sözdizimi olarak denetleyicide "vm" dışında başka bir ad kullanabiliriz. Başlık altında, AngularJS $ kapsam nesnesini oluşturur ve özellikleri ve davranışı ekler. Bununla birlikte, denetleyiciyi sözdizimi olarak kullanarak, denetleyicide kod çok temizdir ve görünümde yalnızca takma ad görünür.

Denetleyiciyi sözdizimi olarak kullanmak için bazı adımlar:

  1. $ Kapsam nesnesi olmayan bir denetleyici oluşturun.

  2. Bunu yerel bir değişkene atayın. Değişken ismini vm olarak tercih ettim, dilediğiniz ismi seçebilirsiniz.

  3. Vm değişkenine veri ve davranış ekleyin.

  4. Görünümde, denetleyiciyi sözdizimi olarak kullanarak denetleyiciye bir takma ad verin.

  5. Takma ada herhangi bir isim verebilirsiniz. İç içe geçmiş denetleyicilerle çalışmadığım sürece vm kullanmayı tercih ederim.

Denetleyiciyi oluştururken, $ kapsam nesnesi yaklaşımını veya denetleyiciyi sözdizimi olarak kullanmanın doğrudan avantajları veya dezavantajları yoktur. Bu tamamen bir seçim meselesidir, ancak denetleyiciyi sözdizimi olarak kullanmak, denetleyicinin JavaScript kodunu daha okunabilir hale getirir ve bu bağlamla ilgili sorunları önler.

$ Kapsam nesne yaklaşımında iç içe geçmiş denetleyiciler

Aşağıdaki listede gösterildiği gibi iki denetleyicimiz var:

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



    $scope.name = "DJ";

    $scope.age = 32;

});

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



    $scope.age = 22;

    $scope.country = "India";



});

"Yaş" özelliği her iki denetleyicinin içindedir ve görünümde bu iki denetleyici aşağıdaki listede gösterildiği gibi yuvalanabilir:

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

Gördüğünüz gibi, üst denetleyicinin age özelliğine erişmek için $ parent.age kullanıyoruz. Bağlam ayrımı burada çok net değil. Ancak denetleyiciyi sözdizimi olarak kullanarak, iç içe geçmiş denetleyicilerle daha zarif bir şekilde çalışabiliriz. Aşağıdaki listede gösterildiği gibi denetleyicilerimiz olduğunu varsayalım:

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



});

Görünümde, bu iki denetleyici aşağıdaki listede gösterildiği gibi yuvalanabilir:

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

Sözdizimi olarak denetleyicide, daha okunabilir koda sahibiz ve üst özelliğe, $ parent sözdizimi kullanmak yerine üst denetleyicinin takma adı kullanılarak erişilebilir.

Bu yazıyı, denetleyiciyi sözdizimi veya $ kapsam nesnesi olarak kullanmak isteyip istemediğinizin tamamen sizin seçiminiz olduğunu söyleyerek bitireceğim. Her ikisinin de büyük bir avantajı veya dezavantajı yoktur, basitçe bağlam üzerinde kontrolünüz olan kontrolörle çalışmak, görünümdeki iç içe kontrolörlerdeki net ayrım göz önüne alındığında biraz daha kolay.


4

Yöntemler / özellikler, kapsam nesnesi ile değil, doğrudan denetleyici örneğiyle ilişkilendirildiği için ana avantajın daha sezgisel bir API olduğunu düşünüyorum. Temel olarak, eski yaklaşımla, kontrolör sadece osiloskop nesnesini oluşturmak için bir dekorasyon haline gelir.

İşte bununla ilgili daha fazla bilgi: http://www.syntaxsuccess.com/viewarticle/551798f20c5f3f3c0ffcc9ff


3

Okuduklarıma göre, $ kapsam Angular 2.0'da veya en azından $ kapsamın kullanımını nasıl gördüğümüzde kaldırılacak. 2.0 sürümü yaklaşırken denetleyiciyi kullanmaya başlamak iyi olabilir.

Bununla ilgili daha fazla tartışma için buradaki video bağlantısı .

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.