Appeler une méthode d'un controller à partir d'un autre controller en utilisant 'scope' dans AngularJS

j'essaye d'appeler une méthode de second controller dans first controller en utilisant scope variable. C'est une méthode dans mon premier contrôleur:

$scope.initRestId = function(){
        var catapp = document.getElementById('SecondApp');
        var catscope = angular.element(catapp).scope();
        catscope.rest_id = $scope.user.username;
        catscope.getMainCategories();
    }; 

je suis en mesure de définir la valeur de rest_id mais je ne peux pas appeler getMainCategories pour une raison quelconque. La console affiche cette erreur:

TypeError: Object # n'a pas de méthode 'getMainCategories'

Est-il possible d'appeler la méthode ci-dessus?

Edit:

je utilisé l'approche suivante pour charger deux applications en même temps;

angular.bootstrap(document.getElementById('firstAppID'), ['firstApp']);
angular.bootstrap(document.getElementById('secondAppID'), ['secondApp']);

je pourrais certainement utiliser un service ici, mais je voulais savoir s'il y avait d'autres options pour faire la même chose!

43
demandé sur isherwood 2013-10-19 20:31:10

3 réponses

la meilleure approche pour communiquer entre les deux contrôleurs est d'utiliser les événements.

Documentation Sur La Portée

dans ce check out $on, $broadcast et $emit.

dans le cas d'utilisation générale, l'utilisation de angular.element(catapp).scope() a été conçu pour être utilisé à l'extérieur des contrôleurs angulaires, comme dans les événements jquery.

idéalement, dans votre usage, vous écririez un événement dans le controller 1 comme:

$scope.$on("myEvent", function (event, args) {
   $scope.rest_id = args.username;
   $scope.getMainCategories();
});

et dans la seconde contrôleur de vous venais de faire

$scope.initRestId = function(){
   $scope.$broadcast("myEvent", {username: $scope.user.username });
};

Edit: Réalisé que c'était la communication entre les deux modules

pouvez-vous essayer d'inclure le firstApp module comme une dépendance à la secondApp où vous déclarez l' angular.module. De cette façon, vous pouvez communiquer à l'autre application.

62
répondu Praveenram Balachandar 2015-03-27 19:55:50

Voici une bonne démo en Tripoter comment utiliser le service partagé dans la directive et les autres contrôleurs par $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;
});

de la même façon que nous pouvons utiliser le service partagé dans la directive. Nous pouvons implémenter la section controller en directive et utiliser $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>'
    };
});

et voici trois nos contrôleurs où ControllerZero utilisé comme déclencheur d'invoquer 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 et ControllerTwo écouter message modifier à l'aide de $scope.$on gestionnaire.

25
répondu Maxim Shoustin 2013-10-19 17:57:19

chaque controller a son propre scope(s) donc cela cause votre problème.

Avoir deux contrôleurs qui veulent avoir accès aux mêmes données est un signe classique que vous voulez un service. L'équipe d'angular recommande des contrôleurs minces qui ne font que coller entre les vues et les services. Et plus précisément - "les services devraient être partagés entre les contrôleurs".

heureusement, il y a une belle vidéo de 15 minutes qui décrit exactement ceci (communication contrôleur via services):vidéo

L'un des Auteurs originaux D'Angular, Misko Hevery, discute de cette recommandation (d'utiliser les services dans cette situation) dans son exposé intitulé Pratiques Exemplaires Angulaires (passer à 28: 08 pour ce sujet, bien que j'ai fortement recommandé de regarder l'ensemble de la discussion).

vous pouvez utiliser des événements, mais ils sont conçus uniquement pour la communication entre deux parties qui veulent être découplées. Dans la vidéo ci-dessus, Misko note comment ils peut rendre votre application plus fragiles. "la plupart du temps, les services d'injection et de communication directe sont préférés et plus robustes". (Voir le lien ci-dessus à partir de 53: 37 pour l'entendre parler de cela)

24
répondu KayakDave 2017-01-18 13:28:23