Вызовите метод контроллера с другого контроллера, используя 'scope' в AngularJS
Я пытаюсь вызвать метод второго контроллера в первом контроллере с помощью переменной scope
. Это мой первый контроллер:
$scope.initRestId = function(){
var catapp = document.getElementById('SecondApp');
var catscope = angular.element(catapp).scope();
catscope.rest_id = $scope.user.username;
catscope.getMainCategories();
};
Я могу установить значение rest_id
, но по какой-то причине я не могу вызвать getMainCategories
. Консоль показывает эту ошибку:
TypeError: Объект # не имеет метода 'getMainCategories'
Есть ли способ вызвать вышеупомянутый метод?
Edit:
Я использовал следующий подход для загрузки двух приложений одновременно:
angular.bootstrap(document.getElementById('firstAppID'), ['firstApp']);
angular.bootstrap(document.getElementById('secondAppID'), ['secondApp']);
Я мог бы определенно использовать сервис здесь, но я хотел знать, есть ли другие варианты для этого!
Ответы
Ответ 1
Наилучшим подходом для общения между двумя контроллерами является использование событий.
Документация по области
В этом случае проверьте $on
, $broadcast
и $emit
.
В общем случае использование angular.element(catapp).scope()
предназначено для использования вне контроллеров angular, например, в событиях jquery.
В идеале в вашем использовании вы должны написать событие в контроллере 1 как:
$scope.$on("myEvent", function (event, args) {
$scope.rest_id = args.username;
$scope.getMainCategories();
});
И во втором контроллере вы просто выполните
$scope.initRestId = function(){
$scope.$broadcast("myEvent", {username: $scope.user.username });
};
Изменить: реализовано, что это была связь между двумя модулями
Можете ли вы попробовать включить модуль firstApp
в качестве зависимости от secondApp
, где вы объявляете angular.module
. Таким образом, вы можете общаться с другим приложением.
Ответ 2
Вот хорошая демонстрация в Fiddle, как использовать общую службу в директиве и других контроллерах через $scope.$on
HTML
<div ng-controller="ControllerZero">
<input ng-model="message" >
<button ng-click="handleClick(message);">BROADCAST</button>
</div>
<div ng-controller="ControllerOne">
<input ng-model="message" >
</div>
<div ng-controller="ControllerTwo">
<input ng-model="message" >
</div>
<my-component ng-model="message"></my-component>
JS
var myModule = angular.module('myModule', []);
myModule.factory('mySharedService', function($rootScope) {
var sharedService = {};
sharedService.message = '';
sharedService.prepForBroadcast = function(msg) {
this.message = msg;
this.broadcastItem();
};
sharedService.broadcastItem = function() {
$rootScope.$broadcast('handleBroadcast');
};
return sharedService;
});
Таким же образом мы можем использовать разделяемую службу в директиве. Мы можем реализовать секцию контроллера в директиве и использовать $scope.$on
myModule.directive('myComponent', function(mySharedService) {
return {
restrict: 'E',
controller: function($scope, $attrs, mySharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = 'Directive: ' + mySharedService.message;
});
},
replace: true,
template: '<input>'
};
});
И вот три наших контроллера, где ControllerZero
используется как триггер для вызова prepForBroadcast
function ControllerZero($scope, sharedService) {
$scope.handleClick = function(msg) {
sharedService.prepForBroadcast(msg);
};
$scope.$on('handleBroadcast', function() {
$scope.message = sharedService.message;
});
}
function ControllerOne($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = 'ONE: ' + sharedService.message;
});
}
function ControllerTwo($scope, sharedService) {
$scope.$on('handleBroadcast', function() {
$scope.message = 'TWO: ' + sharedService.message;
});
}
Отмените ControllerOne
и ControllerTwo
прослушивание message
с помощью обработчика $scope.$on
.
Ответ 3
Каждый контроллер имеет свои собственные области (области), чтобы вызвать вашу проблему.
Наличие двух контроллеров, которые хотят получить доступ к тем же данным, является классическим признаком того, что вы хотите использовать. Команда angular рекомендует тонкие контроллеры, которые просто склеиваются между видами и службами. И в частности - "службы должны поддерживать общее состояние между контроллерами".
К счастью, есть приятное 15-минутное видео, описывающее именно это (связь с контроллером через службы): видео
Один из оригинальных авторов Angular, Misko Hevery, обсуждает эту рекомендацию (об использовании сервисов в этой ситуации) в своем разговоре под названием Angular Лучшие практики (перейдите к 28:08 для этой темы, хотя я очень рекомендую посмотреть весь разговор).
Вы можете использовать события, но они предназначены только для связи между двумя сторонами, которые хотят быть развязаны. В вышеупомянутом видео Misko отмечает, как сделать приложение более хрупким. "Большую часть времени инъекционные услуги и прямая связь предпочтительнее и надежнее" . (Ознакомьтесь с приведенной выше ссылкой, начиная с 53:37, чтобы услышать, как он говорит об этом)