javascript 不同选项卡中控制器之间的Angularjs通信
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19270932/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Angularjs communication between controllers in different tabs
提问by hyperN
I have controller A which sends some data to shared service and controller B which should read that data. The problem is Controller B is on a different page (on same website) than controller A, i.e. I do smth. on controller A, click button (which sends data to service) and open another page where is controller B which should read data from service. But nothing happens, so my question is can controllers on different pages communicate this way ?
我有控制器 A 将一些数据发送到共享服务,控制器 B 应该读取该数据。问题是控制器 B 与控制器 A 位于不同的页面(在同一网站上),即我做某事。在控制器 A 上,单击按钮(将数据发送到服务)并打开另一个页面,其中控制器 B 应从服务读取数据。但是没有任何反应,所以我的问题是不同页面上的控制器可以通过这种方式进行通信吗?
Here is how I tried to do it but with no luck:
这是我尝试这样做但没有运气的方法:
Service:
服务:
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;
});
Relevant parts of controller A:
控制器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);
};
Relevant parts of controller B:
控制器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);
});
});
And even console.log("TEST");
isn't fired.
甚至console.log("TEST");
没有被解雇。
采纳答案by Sebastian Piskorski
Well there are also two other ways to communicate between tabs. Via cookies with global domain, which is not recommended as not secure.
好吧,还有两种其他方式可以在选项卡之间进行通信。通过具有全局域的 cookie,不建议这样做,因为不安全。
Or with postMessage:
或者使用 postMessage:
https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage?redirectlocale=en-US
https://developer.mozilla.org/en-US/docs/Web/API/window.postMessage?redirectlocale=en-US
Demo:
演示:
http://html5demos.com/postmessage2
http://html5demos.com/postmessage2
And browser support:
和浏览器支持:
回答by Anton
based on your question
根据你的问题
my question is can controllers on different pages communicate this way ?
我的问题是不同页面上的控制器可以通过这种方式进行通信吗?
The answer is no. Angular and javascript for that matter are not designed like that.
答案是不。Angular 和 javascript 并不是这样设计的。
If however you mean different views on the same page, then yes, you can use a service. Services are singletons and keep their data across controllers when kept on the same page.
但是,如果您指的是同一页面上的不同视图,那么是的,您可以使用服务。服务是单例的,当保存在同一页面上时,它们的数据会跨控制器保存。
If you really want to send data from one page to another your options are to do it via a querystring(on the url) or posting the data, or if you are supporting only modern browsers then you can use the client side local storage (http://www.w3schools.com/html/html5_webstorage.asp)
如果您真的想将数据从一个页面发送到另一个页面,您的选择是通过查询字符串(在 url 上)或发布数据,或者如果您只支持现代浏览器,那么您可以使用客户端本地存储(http ://www.w3schools.com/html/html5_webstorage.asp)
回答by codef0rmer
I assume when you jump between tabs, you are unfortunately reloading the entire page - Do not do that. Instead use routeProviderto setup a nice routing.
我假设当您在选项卡之间跳转时,不幸的是您正在重新加载整个页面 - 不要这样做。而是使用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'});
});
Then the rest of your code would work and retain the shared data stored by the service even when you switch tabs. In case, you do not want to use the $routeProvider
then write a logic in your service to persist the data using localStorage, indexDB, etc.
然后,即使您切换选项卡,您的其余代码也会工作并保留服务存储的共享数据。如果您不想使用$routeProvider
then 在您的服务中编写逻辑来使用 localStorage、indexDB 等持久化数据。
As far as I can see,you are using Angular controllers and services then it should not be a problem using $routes too. :-)
据我所知,您使用的是 Angular 控制器和服务,那么使用 $routes 也不会有问题。 :-)
回答by Chandermani
$rootScope.$broadcast
is a perfectly acceptable way to communicate between controller, but since you are using across page it would not work. This is because when your do the broadcast
call the other controller is not loaded and hence it's on
method does not get fired. But since your service has a property data
you can directly access it by injecting the service into the other controller and access it's data
property
$rootScope.$broadcast
是一种在控制器之间进行通信的完全可以接受的方式,但是由于您使用的是跨页面,因此它不起作用。这是因为当您broadcast
调用时,未加载另一个控制器,因此它的on
方法不会被触发。但是由于您的服务有一个属性,data
您可以通过将服务注入另一个控制器并访问它的data
属性来直接访问它
controllerCommunicationService.data
anytime and anywhere you want so no need for using on
method.
controllerCommunicationService.data
随时随地都可以,因此无需使用on
方法。
As explained by @Anton you can also pass data using querystring\url fragements and client storage.
正如@Anton 所解释的,您还可以使用 querystring\url 片段和客户端存储来传递数据。