Подтвердить что ты не робот

Вызовите метод контроллера с другого контроллера, используя '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']);

Я мог бы определенно использовать сервис здесь, но я хотел знать, есть ли другие варианты для этого!

4b9b3361

Ответ 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, чтобы услышать, как он говорит об этом)