Angularjs yönergesinde bir denetleyiciye nasıl ihtiyaç duyulur


86

Biri bana bir yönergeden bir denetleyiciyi başka bir angularJS yönergesine nasıl dahil edeceğimi söyleyebilir mi? örneğin şu koda sahibim

var app = angular.module('shop', []).
config(['$routeProvider', function ($routeProvider) {
    $routeProvider.when('/', {
        templateUrl: '/js/partials/home.html'
    })
        .when('/products', {
        controller: 'ProductsController',
        templateUrl: '/js/partials/products.html'
    })
        .when('/products/:productId', {
        controller: 'ProductController',
        templateUrl: '/js/partials/product.html'
    });
}]);

app.directive('mainCtrl', function () {
    return {
        controller: function ($scope) {}
    };
});

app.directive('addProduct', function () {
    return {
        restrict: 'C',
        require: '^mainCtrl',
        link: function (scope, lElement, attrs, mainCtrl) {
            //console.log(cartController);
        }
    };
});

Her halükarda, addProduct yönergesinde denetleyiciye erişebilmeliyim ama değilim. Bunu yapmanın daha iyi bir yolu var mı?


5
requirebaşka bir direktifin varlığını sağlar ve ardından onun denetleyicisini içerir. ^requiremevcut öğeye ek olarak mevcut öğenin üzerindeki öğeleri kontrol eder. Yani bunun işe yaraması için iki yönergeyi birlikte kullanmanız gerekir. Aksi takdirde, sadece bir denetleyici tanımlayın app.controllerve ardından onu her iki yönergede kullanın. Her iki durumda da, bunu HTML kodunuzla birlikte basit bir Plunker'a koyabilir misiniz?
Josh David Miller

Yanıtlar:


187

Şanslıydım ve bunu soruya bir yorumda yanıtladım, ancak eksiksizlik uğruna tam bir yanıt gönderiyorum ve böylece bu soruyu "Yanıtlandı" olarak işaretleyebiliriz.


Bir denetleyiciyi paylaşarak neyi başarmak istediğinize bağlıdır; aynı denetleyiciyi (farklı örneklere sahip olsa da) paylaşabilir veya aynı denetleyici örneğini paylaşabilirsiniz.

Bir Denetleyiciyi Paylaşın

İki yönerge aynı yöntemi iki yönergeye geçirerek aynı denetleyiciyi kullanabilir, örneğin:

app.controller( 'MyCtrl', function ( $scope ) {
  // do stuff...
});

app.directive( 'directiveOne', function () {
  return {
    controller: 'MyCtrl'
  };
});

app.directive( 'directiveTwo', function () {
  return {
    controller: 'MyCtrl'
  };
});

Her yönerge, denetleyicinin kendi örneğini alacaktır, ancak bu, mantığı istediğiniz kadar bileşen arasında paylaşmanıza olanak tanır.

Bir Denetleyici Gerektirir

Bir denetleyicinin aynı örneğini paylaşmak istiyorsanız , kullanırsınız require.

requirebaşka bir yönergenin varlığını sağlar ve daha sonra denetleyicisini bağlantı işlevine bir parametre olarak dahil eder. Dolayısıyla, bir öğe üzerinde iki yönergeniz varsa, yönergeniz diğer yönergenin varlığını gerektirebilir ve denetleyici yöntemlerine erişim sağlayabilir. Bunun için ortak bir kullanım durumu gerektirmektir ngModel.

^require, imleci ekleyerek, diğer yönergeyi bulmaya çalışmak için geçerli öğeye ek olarak yönergenin üzerindeki öğeleri de kontrol eder. Bu, "alt bileşenlerin" büyük bir etki için denetleyicisi aracılığıyla ana bileşenle iletişim kurabildiği karmaşık bileşenler oluşturmanıza olanak tanır. Örnekler arasında, her bölmenin geçişi işlemek için genel sekmelerle iletişim kurabildiği sekmeler yer alabilir; bir akordeon seti aynı anda yalnızca birinin açık olmasını sağlayabilir; vb.

Her iki durumda da, bunun çalışması için iki yönergeyi birlikte kullanmanız gerekir. requirebileşenler arasında iletişim kurmanın bir yoludur.

Daha fazla bilgi için yönergelerin Kılavuz sayfasına bakın: http://docs.angularjs.org/guide/directive


4
Kardeş yönerge denetleyicisine ihtiyaç duyulabilir mi? Temel olarak, ng-tekrar kullanarak tekrarlanan kardeş yönergeler arasında (aynı DOM öğesinde değil, DOM kardeşlerinde olduğu gibi) aynı denetleyici veya hizmet örneğini paylaşmam gerekiyor. Tekrarlanan her öğenin, aralarında paylaşılan bir duruma veya mantığa ihtiyaç duyan bir yönergesi olduğunu hayal edin.
CMCDragonkai

2
@CMCDragonkai Bunu yapmanın bir yolu yok, ancak aynı şeyi başarmanın iki yaygın yolu var. Birincisi, kardeşlerin hepsi aynı "tipte" ise, ngRepeat üzerindeki eleman bir konteyner yönergesi gibi olabilir ve tüm alt elemanlar bunun yerine bu yönergeyi gerektirebilir, hepsi aynı denetleyiciyi paylaşır. Daha yaygın ve genellikle daha kurallı olan çözüm, paylaşılan bir hizmet kullanmaktır. Bu kardeşlerin ne yaptıklarını ve neleri paylaşmaları gerektiğini açıklar mısınız?
Josh David Miller

Evet, ilk seçeneği yaptı. Bir kapsayıcı yönerge denetleyicisi kullanma. Harika çalışıyor. Masonluk için.
CMCDragonkai

Bu harika bir cevap ve tüm bunların nasıl çalıştığına dair anlayışımı pekiştirdi. Teşekkürler! (Not olarak, bu daha yeni bir özellik olabilir, ancak requiretek bir yönerge veya bir dizi yönerge belirtmek için kullanabilirsiniz ; ^daha ayrıntılı gereksinimler için her yönergenin önüne bir
düzeltme

Aynı denetleyiciyi iki yönergede kullanmak, her yönergeye kendi örneğini vermez.
jsbisht

27

Mark Rajcok'un burada iyi bir yığın aşımı cevabı var:

Ana yönerge denetleyicileri gerektiren AngularJS yönergesi denetleyicileri?

bu çok net jsFiddle bağlantısıyla: http://jsfiddle.net/mrajcok/StXFK/

<div ng-controller="MyCtrl">
    <div screen>
        <div component>
            <div widget>
                <button ng-click="widgetIt()">Woo Hoo</button>
            </div>
        </div>
    </div>
</div>

JavaScript

var myApp = angular.module('myApp',[])

.directive('screen', function() {
    return {
        scope: true,
        controller: function() {
            this.doSomethingScreeny = function() {
                alert("screeny!");
            }
        }
    }
})

.directive('component', function() {
    return {
        scope: true,
        require: '^screen',
        controller: function($scope) {
            this.componentFunction = function() {
                $scope.screenCtrl.doSomethingScreeny();
            }
        },
        link: function(scope, element, attrs, screenCtrl) {
            scope.screenCtrl = screenCtrl
        }
    }
})

.directive('widget', function() {
    return {
        scope: true,
        require: "^component",
        link: function(scope, element, attrs, componentCtrl) {
            scope.widgetIt = function() {
                componentCtrl.componentFunction();
            };
        }
    }
})


//myApp.directive('myDirective', function() {});
//myApp.factory('myService', function() {});

function MyCtrl($scope) {
    $scope.name = 'Superhero';
}

4
Benim için Mark Rajcok'un örneğini en çok tıklayan şey, denetleyici yöntemlerinin nasıl oluşturulduğuna dikkat etmekti. Normalde $ kapsam.methodName = function () {...} aracılığıyla oluşturulan denetleyici yöntemlerini görürsünüz, ancak bunun çalışması için, erişilebilir olmasını istediğiniz yöntemler için this.methodName'i kullanmanız gerekir. Bunu ilk başta fark etmedim.
coblr
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.