2013-05-23 16 views
31

Ich baue eine E-Commerce-Site (basierend auf shopify) und ich benutze mehrere kleine angularjs apps, um Dinge wie einen schnellen Warenkorb, Wunschlisten, Filterprodukte und a einige andere kleinere Gegenstände. Ich verwendete anfangs eine große Anwendung (die Routing und alles hatte), aber es war ein bisschen zu restriktiv, wenn ich nicht eine vollständige REST API hatte.Teilen Sie einen einzigen Dienst zwischen mehreren angular.js apps

Es gibt ein paar Dienste, die ich zwischen den eckigen Apps (der Warenkorb-Service, so dass ich eine schnelle Schaltfläche hinzufügen kann, die in den Mini-Warenkorb und dergleichen widerspiegeln) möchte, aber ich bin nicht sicher der beste Weg (wenn es einen Weg gibt), um darüber zu gehen. Durch das Teilen eines Moduls mit dem Dienst wird nicht der gleiche Status in den Apps beibehalten.

Ich habe versucht, meine Hand, aber ich es scheint nicht den Status zwischen beiden Apps zu aktualisieren. Das folgende ist das Javascript, das ich versuchte zu verwenden. Es ist auch auf jsfiddle mit begleitender 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']); 

Jede mögliche Hilfe

Antwort

24

Die sharedService geschätzt werden wird geteilt, aber ein Winkel App nicht weiß, dass etwas in der anderen App aktualisiert, so dass es doesn‘ t einen $digest starten. Sie müssen manuell die $rootScope jeder Anwendung anweisen, eine $digest durch den Aufruf $rootscope.$apply()

Fiddle zu starten: 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; 
    }); 
+0

geschieht, die gut funktioniert. Wie würden Sie vorschlagen, dass ich die $ window.rootScopes-Sache mit mehreren Shared Services mache? Ich würde vermuten, es würde verdoppeln, wenn ich nicht vorsichtig war –

+0

Ah, keine Sorge, ich fand einen guten Weg, es zu tun - legte es in einen Lauf Block in den Apps, nicht die freigegebenen Module –

+0

@ TomBrunoli können Sie erarbeiten Was hast du gemacht? Wie haben Sie den Service-Code fehlerfrei aus den freigegebenen Modulen in den Run-Block der Apps verschoben? – kevin11

3

ich ein ähnliches Problem zu lösen versuchte. Teilen von Fabriken zwischen Apps, die in verschiedenen iFrames ausgeführt werden. Ich wollte alle $apply() in einem beliebigen Rahmen, um einen Digest-Zyklus in allen anderen Frames zu verursachen. Erlauben einfach ng-clicks gebunden direkt an eine Factory-Methode, um die Ansicht in allen anderen Frames zu aktualisieren. Ich habe ein Modul, das die Bindung von Bereichen und die gemeinsame Nutzung von Fabriken Griffe:

Click here to see plunkr

einfach das Modul auf jedem App gehört:

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

Und ändern return-Anweisung jeder Fabrik die gemeinsame Version zurückkehren dieser Fabrik:

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

zB

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

Zähler Updates in beiden Frames, wenn Klick in beiden

Verwandte Themen