2013-03-28 8 views
79

Czy ktoś może mi powiedzieć, jak dołączyć kontroler z jednej dyrektywy do innej dyrektywy kątowej JS? na przykład mam następujący kodJak wymagać kontrolera w dyrektywie angularjs?

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); 
     } 
    }; 
}); 

przez wszystkie konta powinny być w stanie uzyskać dostęp do kontrolera w dyrektywie addProduct ale nie jestem. Czy jest lepszy sposób na zrobienie tego?

+4

'require' zapewnia obecność innej dyrektywy, a następnie zawiera jej kontroler. '^ require' sprawdza elementy powyżej bieżącego oprócz bieżącego elementu. Aby to zadziałało, musisz użyć obu dyrektyw. W przeciwnym razie po prostu zdefiniuj kontroler za pomocą 'app.controller', a następnie użyj go w obu dyrektywach. Tak czy inaczej, czy możesz umieścić to w prostym Plunkerze wraz z kodem HTML? –

+0

to była odpowiedź –

Odpowiedz

180

Mam szczęście i odpowiedziałem na to w komentarzu do pytania, ale publikuję pełną odpowiedź dla zachowania kompletności, więc możemy oznaczyć to pytanie jako "Odpowiedzi".


To zależy od tego, co chcesz osiągnąć, dzieląc się kontrolerem; możesz współużytkować ten sam kontroler (choć mają różne instancje) lub współużytkować tę samą instancję kontrolera.

Podziel kontroler

dwóch dyrektyw mogą używać tego samego kontrolera, przekazując tę ​​samą metodę do dwóch dyrektyw, tak jak poniżej:

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

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

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

każdej dyrektywy dostanie własną instancję kontrolera, ale to pozwala ci dzielić logikę między tylu komponentami, ile chcesz.

wymagają kontrolera

Jeśli chcesz udostępnić ten sam instancji kontrolera, a następnie użyć require.

require zapewnia obecność innej dyrektywy, a następnie zawiera jej kontroler jako parametr funkcji łącza. Jeśli więc masz dwie dyrektywy na jednym elemencie, twoja dyrektywa może wymagać obecności innej dyrektywy i uzyskać dostęp do jej metod kontrolera. Powszechnym zastosowaniem tego rozwiązania jest wymaganie ngModel.

^require, z dodatkiem karetki, sprawdza elementy powyżej dyrektywy oprócz bieżącego elementu, aby znaleźć drugą dyrektywę. Pozwala to na tworzenie złożonych komponentów, w których "podkomponenty" mogą komunikować się z elementem nadrzędnym za pośrednictwem kontrolera, aby uzyskać doskonały efekt. Przykłady mogą obejmować zakładki, w których każdy panel może komunikować się z ogólnymi zakładkami, aby obsłużyć przełączanie; zestaw akordeonu mógłby zapewnić, że tylko jeden jest otwarty na raz; itd.

W obu przypadkach trzeba użyć obu dyrektyw, aby to zadziałało. require to sposób komunikacji między komponentami.

Wyjazd stronę Przewodnik dyrektyw o więcej informacji: http://docs.angularjs.org/guide/directive

+0

dzięki za odpowiedź, która zdecydowanie to zrobiła. –

+2

Czy można wymagać kontrolera dyrektywy rodzeństwa? Zasadniczo muszę udostępnić to samo wystąpienie kontrolera lub usługi między dyrektywami rodzeństwa (jak w rodzeństwie DOM, a nie na tym samym elemencie DOM), który jest powtarzany przy użyciu polecenia ng-repeat. Wyobraź sobie, że każdy powtarzany element ma dyrektywę, która wymaga wspólnego stanu lub logiki między nimi. – CMCDragonkai

+2

@CMCDragonkai Nie ma sposobu, aby to zrobić, ale są dwa popularne sposoby osiągnięcia tego samego. Po pierwsze, jeśli rodzeństwo jest tego samego "typu", to element powyżej ngRepeat może być jak dyrektywa kontenerowa, a wszystkie podelementy mogą wymagać tej dyrektywy zamiast wszystkich, dzieląc ten sam kontroler. Bardziej powszechnym rozwiązaniem - i często bardziej kanonicznym - jest korzystanie z usługi wspólnej. Czy możesz wyjaśnić, co robią te rodzeństwo i co muszą udostępnić? –

27

Jest dobry stackoverflow odpowiedź tutaj Mark Rajcok:

AngularJS directive controllers requiring parent directive controllers?

z linkiem do tego bardzo jasny jsFiddle: 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

+4

Dla mnie najbardziej klikniętym przykładem Marka Rajcoka było zwrócenie uwagi na sposób tworzenia metod kontrolera. Zwykle widać metody kontrolera utworzone za pomocą $ scope.methodName = function() {...}, ale aby to zadziałało, musisz użyć this.methodName dla metod, które chcesz uzyskać. Na początku tego nie zauważyłem. – coblr

Powiązane problemy