2015-06-03 3 views
8

У меня есть один контроллер, который я считаю своим «корневым» контроллером, он объявлен с атрибутом ng-controller, а затем несколькими другими контроллерами, которые динамически создаются с помощью $routeProvider. Я хочу объявить функцию, которая будет доступна через атрибут ng-click в рамках любого из динамических/дочерних контроллеров.Доступ к «текущему» диапазону от «корневого» контроллера

Я могу объявить функцию на моем корневом контроллере, например.

$scope.announce = function() { 
    alert($scope.specificName); 
} 

тогда я вижу его на всех областях для всех контроллеров «ребенок», но $scope используется в этой функции является локальным по отношению к корневому контроллеру, а не активный в данный момент сфера/контроллера. Как я могу получить доступ к активной, дочерней сфере в этой функции?

+0

Вы можете добавить некоторые варианты использования вашей функции? (Используете ли вы его с помощью ng-click? Внутри другой функции? И т. Д.) – Okazari

+1

Вы всегда можете использовать фабрики и эмитент событий для связи между контроллерами. У меня есть аналогичная вещь с контроллером меню, который обновляется каждый раз при входе или выходе из журналов или добавляет что-то в корзину покупок ... Я не знаю, так ли это по тому же пути? –

ответ

3

Вы можете просто передать сферу ребенка в качестве параметра:

В вашей "корневой" контроллер:

$scope.announce = function (childScope) { 
    alert(childScope.specificName); 
}; 

В контроллере "ребенок":

$scope.announce($scope); 

Или, так как вы необходимо вызвать функцию от ng-click:
В вашем «детском» контроллере:

$scope.callAnnounce = function(){ 
    $scope.announce($scope) 
}; 

Преимущество в том, что вы можете иметь один и тот же код в своих дочерних контроллерах и изменять его только в корневом контроллере, если вам нужно отредактировать функциональность.

+0

Это означает, что я должен объявить функцию, которая называет «анонс» в каждом дочернем контроллере, чего я бы предпочел избежать, но это не поезд, если я должен. – ProfK

+1

Э, нет, нет. Вы можете объявить функцию анонса в корневом контроллере. Затем вы можете просто использовать его в своих дочерних контроллерах. – Cerbrus

+0

Я хочу вызвать 'announce' из функции' ng-click', и я думаю, что этой функции придется передавать '$ scope' для' объявления', и мне кажется эта функция должна существовать в каждом контроллере. – ProfK

5

У меня есть что-то работающее в этом plunker, которое покрывает некоторые удобства.

Функция примет параметр. Этот параметр будет иметь одно и то же имя в каждой области.

<body ng-app="MyApp"> 
    <div ng-controller="mainCtrl"> 
    <button ng-click="announce(specificName)">announce in main</button> 
    <div ng-controller="subCtrl"> 
     <button ng-click="announce(specificName)">announce in sub</button> 
    </div> 
    </div> 
</body> 

Вы главный вид такой же контроллер:

angular.module('MyApp').controller('mainCtrl', function($scope, ItemService){ 

    $scope.specificName = "I'm main !"; 
    $scope.announce = function(specificName){ 
     alert(specificName); 
    } 

}); 

И только переопределить "specificName" вар в контроллере суб:

angular.module('MyApp').controller('subCtrl', function($scope, ItemService){ 

    $scope.specificName = "I'm a sub !"; 

}); 

Для вызова функции в чистом JS вы можете сделайте это в каждом контроллере:

$scope.announce($scope.specificName); 

EDIT:

Я только что понял, что есть другое решение, которое может удовлетворить ваши потребности. Вы можете использовать фабрику или службу для совместного использования функции.

Как услуга может выглядеть:

myApp.service("AnnounceService", 
    function(){ 
     var service = {}; 

     service.announce = function(toAnnounce){ 
       alert(toAnnounce); 
     } 

     return service; 
    } 
); 

Как ваш контроллер будет выглядеть следующим образом:

angular.module('MyApp').controller('subCtrl', function($scope, AnnounceService){ 

    $scope.announce = AnnounceService.announce; 
    $scope.specificName = "I'm a sub !"; 

    //Equivalent 
    $scope.announce($scope.specificName); 
    AnnounceService.announce($scope.specificName); 

}); 

Это то же самое, что вам нужно объявить specificName в каждом контроллере и передать его функция. Но функция будет использоваться в любой части вашего приложения. Вам просто нужно вводить сервис и

Детали:

Наконец абстрактная часть в не функциях, но имя вашего вара в каждом контроллере. Это обычное название.

Если этот var связан с государством, вы можете добавить его в определение состояния. (Если это так, я мог бы попытаться привести вам пример.)

Я также не рекомендую вообще предоставлять полный $ scope другому. Это не очень хорошая практика в угловой.

Надеясь, что это решило вашу проблему или дало достаточное количество подсказок.

Не стесняйтесь задавать более конкретные вопросы, я отредактирую ответ, чтобы адаптировать его к вашим потребностям.

+1

Спасибо за очень полезный ответ, но Cerbrus сначала решил мою проблему. – ProfK

+1

@ProfK Верно, но имейте в виду, что вы не можете полностью использовать функцию. Это не очень хорошая практика. – Okazari

Смежные вопросы