使用';范围';在AngularJS

使用';范围';在AngularJS,angularjs,angularjs-directive,angularjs-scope,Angularjs,Angularjs Directive,Angularjs Scope,我试图使用scope变量在第一个控制器中调用第二个控制器的方法。这是我的第一个控制器中的一个方法: $scope.initRestId = function(){ var catapp = document.getElementById('SecondApp'); var catscope = angular.element(catapp).scope(); catscope.rest_id = $scope.user.username;

我试图使用
scope
变量在第一个控制器中调用第二个控制器的方法。这是我的第一个控制器中的一个方法:

$scope.initRestId = function(){
        var catapp = document.getElementById('SecondApp');
        var catscope = angular.element(catapp).scope();
        catscope.rest_id = $scope.user.username;
        catscope.getMainCategories();
    }; 
我可以设置
rest\u id
的值,但由于某种原因,我无法调用
getmaincegories
。控制台显示此错误:

TypeError:对象#没有方法“getMainCategories”

有没有办法调用上述方法

编辑:

我使用以下方法同时加载两个应用程序

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

我当然可以在这里使用服务,但我想知道是否还有其他选项可以这样做

每个控制器都有自己的作用域,因此这会导致您的问题

拥有两个想要访问相同数据的控制器是您想要服务的典型标志。angular团队推荐的精简控制器只是视图和服务之间的粘合剂。具体来说,“服务应该在控制器之间保持共享状态”

令人高兴的是,有一段15分钟的视频正好描述了这一点(控制器通过服务进行通信):

Angular的原始作者之一Misko Hevery在他的演讲中讨论了这一建议(在这种情况下使用服务)(关于这个主题跳到28:08,尽管我强烈建议观看整个演讲)


您可以使用事件,但它们只是为希望解耦的双方之间的通信而设计的。在上面的视频中,Misko提到了它们如何使你的应用程序更加脆弱“大多数情况下,注入服务和进行直接通信是首选,而且更可靠”。(从53:37开始查看上面的链接,听他谈论这一点)

在两个控制器之间进行通信的最佳方法是使用事件

在此签出
$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
。这样,您就可以与其他应用程序通信。

这是一个很好的演示,介绍如何通过
$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>'
    };
});
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>
通过同样的方式,我们可以在指令中使用共享服务。我们可以在指令中实现控制器部分,并使用
$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>'
    };
});

管制员
管制员两个
收听
消息
使用
$scope.$on
处理程序进行更改。

谢谢,我编辑了我的问题,我很想知道我的问题是否可以在不使用当前方法作为服务的情况下得到解决?您可以,我更新了我的答案,从作者的angular的一个伟大的讨论,我发现非常有用,如果你想保持“angular way”。但是一定要检查事件-它们也应该知道。事实上,您应该使用
$rootScope.$emit
$scope.$root.$emit
。在和上为$Idem$broadcast@ArifNadeem我将很快向您发送一份工作解决方案。下面是一个使用
$broadcast
的示例@ArifNadeem如果您不想过度设计它,并且它是一个小应用程序,我建议您坚持使用事件。如果您看到太多事件悄悄进入,以方便控制器之间的通信,请停止您正在做的一切,并编写服务。:)这里有一个小提琴,它将使您最初使用的两个模块都能正常工作:)这是一个如何使用简单服务在控制器之间进行通信的非常简单的示例!精彩的。。即使我已经从控制器一在我的服务中设置了值,我也需要确保控制器二知道这一点并相应地更新。你的回答很有魅力。Dmn,我使用Angular已经很多年了,这是我遇到的最漂亮的实现。mySharedService将被重命名,它将在我所有项目中使用的收藏中占据一个荣誉的位置。稍加修饰(即,我相信这些信息需要一个信封),它可以处理98%的通信需求。
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;
    });
}