javascript 在多个 angular.js 应用程序之间共享单个服务
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/16725392/
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
Share a single service between multiple angular.js apps
提问by Tom Brunoli
I'm building an ecommerce site (based on shopify) and I'm using multiple small angularjs apps to handle things such as a quick shopping cart, wishlists, filtering products and a few other smaller items. I initially used one big application (that had routing and everything), but it was a bit to restrictive when I didn't have a full REST API.
我正在构建一个电子商务网站(基于 shopify),并且我正在使用多个小型 angularjs 应用程序来处理诸如快速购物车、愿望清单、过滤产品和其他一些较小的项目之类的事情。我最初使用了一个大型应用程序(具有路由和所有内容),但是当我没有完整的 REST API 时,它有点受限制。
There are a couple of services that I would like to share between the angular apps (the cart service, so I can have a quick add button that will reflect in the mini-cart and such), but I'm not sure of the best way (if there is a way) to go about this. Just sharing a module with the service doesn't keep the same state across the apps.
我想在 Angular 应用程序之间共享一些服务(购物车服务,所以我可以有一个快速添加按钮,该按钮将反映在迷你购物车等中),但我不确定哪个是最好的方法(如果有办法的话)来解决这个问题。只是与服务共享一个模块不会在应用程序之间保持相同的状态。
I tried my hand at it, but I it doesn't seem to update state between both apps. The following is the javascript I tried using. It's also on jsfiddle with accompanying html: http://jsfiddle.net/k9KM7/1/
我试过了,但我似乎没有在两个应用程序之间更新状态。以下是我尝试使用的 javascript。它也在 jsfiddle 上附带 html:http: //jsfiddle.net/k9KM7/1/
angular.module('test-service', [])
.service('TestService', function($window){
var text = 'Initial state';
if (!!$window.sharedService){
return $window.sharedService;
}
$window.sharedService = {
change: function(newText){
text = newText;
},
get: function(){
return text;
}
}
return $window.sharedService;
});
angular.module('app1', ['test-service'])
.controller('App1Ctrl', function($scope, TestService){
$scope.text = function(){ return TestService.get() }
$scope.change = function(){ TestService.change('app 1 activated') }
});
angular.module('app2', ['test-service'])
.controller('App2Ctrl', function($scope, TestService){
$scope.text = function(){ return TestService.get() }
$scope.change = function(){ TestService.change('app 2 activated') }
});
var app1El = document.getElementById('app1');
var app2El = document.getElementById('app2');
angular.bootstrap(app1El, ['app1', 'test-service']);
angular.bootstrap(app2El, ['app2', 'test-service']);
Any help would be appreciated
任何帮助,将不胜感激
采纳答案by Matt York
The sharedService
is being shared, but one angular app doesn't know that something updated in the other app so it doesn't kick off a $digest
. You have to manually tell the $rootScope
of each application to start a $digest
by calling $rootscope.$apply()
将sharedService
被共享,但一个角的应用程序不知道的东西在其他应用程序更新,所以它不揭开序幕$digest
。您必须通过调用手动告诉$rootScope
每个应用程序的启动$digest
$rootscope.$apply()
Fiddle: http://jsfiddle.net/pvtpenguin/k9KM7/3/
小提琴:http: //jsfiddle.net/pvtpenguin/k9KM7/3/
angular.module('test-service', [])
.service('TestService', function($rootScope, $window){
var text = 'Initial state';
$window.rootScopes = $window.rootScopes || [];
$window.rootScopes.push($rootScope);
if (!!$window.sharedService){
return $window.sharedService;
}
$window.sharedService = {
change: function(newText){
text = newText;
angular.forEach($window.rootScopes, function(scope) {
if(!scope.$$phase) {
scope.$apply();
}
});
},
get: function(){
return text;
}
}
return $window.sharedService;
});
回答by Phil Holden
I was trying to solve a similar problem. Sharing factories between apps running in different iFrames. I wanted any $apply()
in any frame to cause a digest cycle in all other frames. Allowing simple ng-clicks
bound directly to a factory method to update the view in all other frames. I created a module which handles the binding of scopes and sharing of factories:
我试图解决类似的问题。在不同 iFrame 中运行的应用程序之间共享工厂。我希望任何$apply()
帧中的任何帧在所有其他帧中引起摘要循环。允许ng-clicks
直接绑定到工厂方法以更新所有其他框架中的视图。我创建了一个处理范围绑定和工厂共享的模块:
Just include the module on each app:
只需在每个应用程序中包含模块:
angular.module('App', ['iFrameBind'])
And change any factory's return statement to return the shared version of that factory:
并更改任何工厂的 return 语句以返回该工厂的共享版本:
return sharedFactory.register('counter', service);
e.g.
例如
.factory('counter', function (sharedFactory) {
var service;
var val = 0;
function inc() {
val++;
}
function dec() {
val--;
}
function value() {
return val;
}
service = {
inc: inc,
dec: dec,
value: value
};
return sharedFactory.register('counter', service);
})
.directive('counter', function (counter) {
return {
template: '{{counter.value()}} ' +
'<button ng-click="counter.inc()">Up</button> ' +
'<button ng-click="counter.dec()">Down</button> ',
restrict: 'E',
link: function postLink(scope) {
scope.counter = counter;
}
};
});
Counter updates in both frames when click happens in either
当点击发生在两个帧中时,计数器更新