Angularjs在不同选项卡中的控制器之间的通信

时间:2013-10-09 11:34:44

标签: javascript angularjs

我有控制器A将一些数据发送到共享服务和控制器B,它应该读取该数据。问题是控制器B与控制器A位于不同的页面(在同一网站上),即我确实是smth。在控制器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");也没有被解雇。

4 个答案:

答案 0 :(得分:7)

根据您的问题

  

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

答案是否定的。对于这个问题,Angular和javascript不是那样设计的。

如果您在同一页面上表示不同的观点,那么是的,您可以使用服务。服务是单例,并在保存在同一页面时将数据保存在控制器中。

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

答案 1 :(得分:5)

还有另外两种方法可以在标签之间进行通信。通过具有全局域名的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 :(得分:3)

我假设当你在标签之间跳转时,不幸的是你重新加载整个页面 - 不要这样做。而是使用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 :(得分:1)

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

来直接访问它。 随时随地

controllerCommunicationService.data,因此无需使用on方法。

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