在多个 angular.js 应用程序之间共享单个服务

IT技术 javascript angularjs
2021-03-09 21:15:06

我正在构建一个电子商务网站(基于 shopify)并且我正在使用多个小型 angularjs 应用程序来处理诸如快速购物车、愿望清单、过滤产品和其他一些较小的项目之类的事情。我最初使用了一个大型应用程序(具有路由和所有内容),但是当我没有完整的 REST API 时,它有点受限制。

我想在 Angular 应用程序之间共享一些服务(购物车服务,所以我可以有一个快速添加按钮,该按钮将反映在迷你购物车等中),但我不确定哪个是最好的方法(如果有办法的话)来解决这个问题。只是与服务共享一个module不会在应用程序之间保持相同的状态。

我试过了,但我似乎没有在两个应用程序之间更新状态。以下是我尝试使用的 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']);

任何帮助,将不胜感激

2个回答

sharedService被共享,但一个角的应用程序不知道的东西在其他应用程序更新,所以它不揭开序幕$digest您必须通过调用手动告诉$rootScope每个应用程序的启动$digest$rootscope.$apply()

小提琴: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;
  });
啊别担心,我想出了一个好方法 - 把它放在应用程序的运行块中,而不是共享module中
2021-04-21 21:15:06
这很好用。你会如何建议我用多个共享服务来做 $window.rootScopes 的事情?如果我不小心,我会认为它会翻倍
2021-04-26 21:15:06
我知道这真的很旧,但不确定这是如何工作的。当我尝试此操作时,每个 windowService rootScope 集合仅具有每个module添加的一个 rootScope,其他module没有其他 rootScope 元素。
2021-04-28 21:15:06
@TomBrunoli 你能详细说明你做了什么吗?你是如何将服务代码从共享module移动到应用程序的运行块而没有错误的?
2021-05-09 21:15:06
@kevin11 我希望我能帮上忙,但我没有代码了。我们最终将所有内容重新分解为一个应用程序。我可能应该在我有解决方案时发布我的解决方案......
2021-05-12 21:15:06

我试图解决类似的问题。在不同 iFrame 中运行的应用程序之间共享工厂。我希望任何$apply()帧中的任何帧在所有其他帧中引起摘要循环。允许ng-clicks直接绑定到工厂方法以更新所有其他框架中的视图。我创建了一个处理范围绑定和工厂共享的module:

点击这里查看plunkr

只需在每个应用程序中包含module:

angular.module('App', ['iFrameBind'])

并更改任何工厂的 return 语句以返回该工厂的共享版本:

return sharedFactory.register('counter', service);

例如

.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;
    }
  };
});

当点击发生在两个帧中时,计数器更新