Ich habe den folgenden Dienst in meiner App:
uaInProgressApp.factory('uaProgressService',
function(uaApiInterface, $timeout, $rootScope){
var factory = {};
factory.taskResource = uaApiInterface.taskResource()
factory.taskList = [];
factory.cron = undefined;
factory.updateTaskList = function() {
factory.taskResource.query(function(data){
factory.taskList = data;
$rootScope.$digest
console.log(factory.taskList);
});
factory.cron = $timeout(factory.updateTaskList, 5000);
}
factory.startCron = function () {
factory.cron = $timeout(factory.updateTaskList, 5000);
}
factory.stopCron = function (){
$timeout.cancel(factory.cron);
}
return factory;
});
Dann benutze ich es in einem Controller wie diesem:
uaInProgressApp.controller('ua.InProgressController',
function ($scope, $rootScope, $routeParams, uaContext, uaProgressService) {
uaContext.getSession().then(function(){
uaContext.appName.set('Testing house');
uaContext.subAppName.set('In progress');
uaProgressService.startCron();
$scope.taskList = uaProgressService.taskList;
});
}
);
Also im Grunde meine Service - Update factory.taskList
alle 5 Sekunden und ich verknüpfen diese factory.taskList
zu $scope.taskList
. Ich habe dann verschiedene Methoden ausprobiert $apply
, $digest
aber Änderungen an factory.taskList
werden nicht in meinem Controller und meiner Ansicht wiedergegeben $scope.taskList
.
Es bleibt in meiner Vorlage leer. Wissen Sie, wie ich diese Änderungen verbreiten kann?
Angular (im Gegensatz zu Ember und einigen anderen Frameworks) bietet keine speziell verpackten Objekte, die halbmagisch synchron bleiben. Die Objekte , die Sie manipulieren sind einfache JavaScript - Objekte und einfach wie zu sagen ,
var a = b;
nicht verknüpfen die Variablena
undb
, sagen$scope.taskList = uaProgressService.taskList
verknüpfen nicht diese beiden Werte.Für diese Art von
link
-ingangular
sorgt$watch
on$scope
. Sie können den Wert von beobachtenuaProgressService.taskList
und den Wert aktualisieren,$scope
wenn er sich ändert:$scope.$watch(function () { return uaProgressService.taskList }, function (newVal, oldVal) { if (typeof newVal !== 'undefined') { $scope.taskList = uaProgressService.taskList; } });
Der erste an die
$watch
Funktion übergebene Ausdruck wird in jeder$digest
Schleife ausgeführt, und das zweite Argument ist die Funktion, die mit dem neuen und dem alten Wert aufgerufen wird.quelle
Ich bin nicht sicher, ob das hilft, aber ich binde die Funktion an $ scope.value. Zum Beispiel
angular .module("testApp", []) .service("myDataService", function(){ this.dataContainer = { valA : "car", valB : "bike" } }) .controller("testCtrl", [ "$scope", "myDataService", function($scope, myDataService){ $scope.data = function(){ return myDataService.dataContainer; }; }]);
Dann binde ich es einfach in DOM als
<li ng-repeat="(key,value) in data() "></li>
Auf diese Weise können Sie vermeiden, $ watch in Ihrem Code zu verwenden.
quelle
Nein
$watch
oder etc. ist erforderlich. Sie können einfach Folgendes definierenuaInProgressApp.controller('ua.InProgressController', function ($scope, $rootScope, $routeParams, uaContext, uaProgressService) { uaContext.getSession().then(function(){ uaContext.appName.set('Testing house'); uaContext.subAppName.set('In progress'); uaProgressService.startCron(); }); $scope.getTaskList = function() { return uaProgressService.taskList; }; });
Da die Funktion
getTaskList
zu$scope
ihrem Rückgabewert gehört, wird sie bei jeder Änderung von ausgewertet (und aktualisiert)uaProgressService.taskList
quelle
Eine einfache Alternative besteht darin, dass Sie während der Controller-Initialisierung ein im Service eingerichtetes Benachrichtigungsmuster abonnieren.
Etwas wie:
app.controller('YourCtrl'['yourSvc', function(yourSvc){ yourSvc.awaitUpdate('YourCtrl',function(){ $scope.someValue = yourSvc.someValue; }); }]);
Und der Service hat so etwas wie:
app.service('yourSvc', ['$http',function($http){ var self = this; self.notificationSubscribers={}; self.awaitUpdate=function(key,callback){ self.notificationSubscribers[key]=callback; }; self.notifySubscribers=function(){ angular.forEach(self.notificationSubscribers, function(callback,key){ callback(); }); }; $http.get('someUrl').then( function(response){ self.importantData=response.data; self.notifySubscribers(); } ); }]);
Auf diese Weise können Sie eine genauere Feinabstimmung vornehmen, wenn Ihre Controller von einem Dienst aktualisiert werden.
quelle
Wie Gabriel Piacenti sagte, werden keine Uhren benötigt, wenn Sie die sich ändernden Daten in ein Objekt einwickeln.
Der folgende Code sollte dies klarer erklären. In meinem Beispiel verwende ich einen NLS-Dienst zum Übersetzen. Die NLS-Token werden über http aktualisiert.
Der Service:
app.factory('nlsService', ['$http', function($http) { var data = { get: { ressources : "gdc.ressources", maintenance : "gdc.mm.maintenance", prewarning : "gdc.mobMaint.prewarning", } }; // ... asynchron change the data.get = ajaxResult.data... return data; }]);
Controller- und Scope-Ausdruck
app.controller('MenuCtrl', function($scope, nlsService) { $scope.NLS = nlsService; } ); <div ng-controller="MenuCtrl"> <span class="navPanelLiItemText">{{NLS.get.maintenance}}</span> </div>
Der obige Code funktioniert, aber zuerst wollte ich direkt auf meine NLS-Token zugreifen (siehe folgendes Snippet) und hier wurden die Werte nicht aktualisiert.
app.controller('MenuCtrl', function($scope, nlsService) { $scope.NLS = nlsService.get; } ); <div ng-controller="MenuCtrl"> <span class="navPanelLiItemText">{{NLS.maintenance}}</span> </div>
quelle