Pregunta Comparta un solo servicio entre múltiples aplicaciones de angular.js


Estoy construyendo un sitio de comercio electrónico (basado en shopify) y estoy usando múltiples aplicaciones pequeñas de angularjs para manejar cosas como un carrito de compras rápido, listas de deseos, productos de filtrado y algunos otros artículos más pequeños. Inicialmente usé una aplicación grande (que tenía enrutamiento y todo), pero fue un poco restrictiva cuando no tenía una API REST completa.

Hay un par de servicios que me gustaría compartir entre las aplicaciones angulares (el servicio de carrito, para que pueda tener un botón de agregar rápido que se reflejará en el carrito pequeño y tal), pero no estoy seguro de cuál es el mejor manera (si hay una forma) de hacerlo. Solo compartir un módulo con el servicio no mantiene el mismo estado en todas las aplicaciones.

Intenté hacerlo, pero parece que no actualizo el estado entre ambas aplicaciones. El siguiente es el javascript que probé usar. También está en jsfiddle con el html que lo acompaña: 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']);

Cualquier ayuda sería apreciada


32
2018-05-23 23:13


origen


Respuestas:


los sharedService se comparte, pero una aplicación angular no sabe que algo se actualizó en la otra aplicación, por lo que no inicia una $digest. Tienes que decirlo manualmente $rootScope de cada aplicación para comenzar una $digest llamando $rootscope.$apply()

Violín: 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;
  });

25
2018-05-24 00:08



Estaba tratando de resolver un problema similar. Compartir fábricas entre aplicaciones que se ejecutan en diferentes iFrames. Yo quería cualquier $apply() en cualquier marco para causar un ciclo de resumen en todos los demás marcos. Permitiendo simple ng-clicks vinculado directamente a un método de fábrica para actualizar la vista en todos los demás marcos. Creé un módulo que maneja el enlace de ámbitos y el intercambio de fábricas:

Haga clic aquí para ver plunkr

Solo incluye el módulo en cada aplicación:

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

Y cambie la declaración de devolución de cualquier fábrica para devolver la versión compartida de esa fábrica:

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

p.ej.

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

Actualizaciones del contador en ambos fotogramas cuando el clic ocurre en cualquiera


3
2017-09-04 16:50