不同选项卡中控制器之间的Angularjs通信[重复]

Posted

技术标签:

【中文标题】不同选项卡中控制器之间的Angularjs通信[重复]【英文标题】:Angularjs communication between controllers in different tabs [duplicate] 【发布时间】:2013-10-16 17:56:01 【问题描述】:

我有控制器 A 向共享服务发送一些数据,控制器 B 应该读取该数据。问题是控制器 B 与控制器 A 位于不同的页面(在同一网站上),即我这样做。在控制器 A 上,单击按钮(将数据发送到服务)并打开另一个页面,其中控制器 B 应该从服务中读取数据。但是什么都没有发生,所以我的问题是不同页面上的控制器可以通过这种方式进行通信吗?

以下是我尝试过但没有成功的方法:

服务:

publicApp.angularModule.service('controllerCommunicationService', function ($rootScope) 
    var communicationService = ;
    communicationService.data = null;

    communicationService.setDataForBroadcast = function(data) 
        this.data = data;
        this.broadcastData();
    ;

    communicationService.broadcastData = function() 
        $rootScope.$broadcast('handleBroadcast');
    ;

    return communicationService;
);

控制器A的相关部分:

publicApp.angularModule.controller('PublicRoutinesCtrl', function ($scope, $rootScope, routinesService, controllerCommunicationService, bootstrapCarouselService) 


    $scope.goToNextScreen = function() 
        var currentIndex = bootstrapCarouselService.getcurrentSlideIndex();
        controllerCommunicationService.setDataForBroadcast($scope.items[currentIndex].Routine.RoutineId);



    ;

控制器B的相关部分:

 $rootScope.$on('handleBroadcast', function () 
        console.log("TEST");
        $http.post("/EditWorkout/PostRoutineId",  routineId: controllerCommunicationService.data )
             .success(function() 
                 console.log("success");
             )
            .error(function (responseData) 
            console.log("Error !" + responseData);
        );
    );

甚至console.log("TEST"); 也没有被解雇。

【问题讨论】:

【参考方案1】:

还有另外两种方法可以在选项卡之间进行通信。通过具有全局域的 cookie,不建议这样做,因为不安全。

或使用 postMessage:

https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage?redirectlocale=en-US

演示:

http://html5demos.com/postmessage2

以及浏览器支持:

http://caniuse.com/#feat=x-doc-messaging

【讨论】:

【参考方案2】:

我假设当您在选项卡之间跳转时,很遗憾您正在重新加载整个页面 - 不要那样做。而是使用routeProvider 来设置一个不错的路由。

var App = angular.module('App', []);
App.config(function($routeProvider) 
  $routeProvider.when('/tab1', templateUrl: 'views/tab1.html');
  $routeProvider.when('/tab2', templateUrl: 'views/tab2.html');
  $routeProvider.otherwise(redirectTo: '/tab1');
);

然后,即使您切换选项卡,您的其余代码也会正常工作并保留服务存储的共享数据。如果您不想使用$routeProvider,则在您的服务中编写一个逻辑,以使用 localStorage、indexDB 等来持久化数据。

据我所知,您正在使用 Angular 控制器和服务,那么使用 $routes 也不应该有问题。 :-)

【讨论】:

【参考方案3】:

$rootScope.$broadcast 是在控制器之间进行通信的一种完全可以接受的方式,但是由于您是跨页面使用,所以它不起作用。这是因为当您执行 broadcast 调用时,未加载另一个控制器,因此它的 on 方法不会被触发。但是由于您的服务有一个属性data,您可以通过将服务注入另一个控制器并访问它的data 属性来直接访问它

controllerCommunicationService.data随时随地随心所欲,无需使用on方法。

正如@Anton 所解释的,您还可以使用 querystring\url 片段和客户端存储来传递数据。

【讨论】:

【参考方案4】:

根据您的问题

我的问题是不同页面上的控制器可以通过这种方式进行通信吗 ?

答案是否定的。 Angular 和 javascript 并不是这样设计的。

但是,如果您指的是同一页面上的不同视图,那么可以,您可以使用服务。服务是单例的,当保存在同一页面上时,它们的数据会跨控制器保存。

如果您真的想将数据从一个页面发送到另一个页面,您的选择是通过查询字符串(在 url 上)或发布数据,或者如果您只支持现代浏览器,那么您可以使用客户端本地存储 (http://www.w3schools.com/html/html5_webstorage.asp)

【讨论】:

更多的是仅供参考,而不是解决方案,但如果您将“controllerCommunicationService.setDataForBroadcast()”放入具有足够延迟的 $timeout 中,则只要目标页面有足够的时间加载,您的代码就可以工作。不过绝对不可靠。

以上是关于不同选项卡中控制器之间的Angularjs通信[重复]的主要内容,如果未能解决你的问题,请参考以下文章

AngularJs选项卡的不同写法

angularjs控制器之间通信,事件通知服务

另一个控制器中的AngularJS调用方法[重复]

在 AngularJS 上使用 Typescript 的指令中控制器的范围

了解AngularJS中控制器的基础知识

使用 AngularJS 中的 UI-Router 将状态重定向到默认子状态