76

アプリに次のサービスがあります。

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

次に、次のようなコントローラーで使用します。

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

したがって、基本的に私のサービスfactory.taskListは5秒ごとに更新され、これをにリンクしfactory.taskListました$scope.taskList$apply次に、のようなさまざまな方法を試し$digestましたが、変更がfactory.taskListコントローラーとビューに反映されません$scope.taskList

私のテンプレートでは空のままです。これらの変更を反映する方法を知っていますか?

4

6 に答える 6

71

Angular (Ember やその他のフレームワークとは異なり) は、半魔法のように同期を保つ特別なラップされたオブジェクトを提供しません。操作しているオブジェクトはプレーンな JavaScript オブジェクトであり、変数と をリンクしないと言っているのと同じように、これら 2 つの値をリンクしていません。var a = b;ab$scope.taskList = uaProgressService.taskList

この種のlink-ing については、 on をangular提供$watch$scopeます。の値を監視し、変更されたときにuaProgressService.taskList値を更新できます。$scope

$scope.$watch(function () { return uaProgressService.taskList }, function (newVal, oldVal) {
    if (typeof newVal !== 'undefined') {
        $scope.taskList = uaProgressService.taskList;
    }
});

関数に渡された最初の式は$watchすべての$digestループで実行され、2 番目の引数は新しい値と古い値で呼び出される関数です。

于 2013-11-02T17:17:27.030 に答える
5

いいえ$watchまたはなどは必要ありません。次のように簡単に定義できます

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.getTaskList = function() {
      return uaProgressService.taskList;
    };
  });

関数はその戻り値にgetTaskList属しているため、$scope変更されるたびに評価 (および更新) されます。uaProgressService.taskList

于 2016-01-05T14:51:34.237 に答える
3

軽量の代替手段は、コントローラーの初期化中に、サービスで設定された通知パターンにサブスクライブすることです。

何かのようなもの:

app.controller('YourCtrl'['yourSvc', function(yourSvc){
    yourSvc.awaitUpdate('YourCtrl',function(){
        $scope.someValue = yourSvc.someValue;
    });
}]);

サービスには次のようなものがあります。

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();
        }
    );
}]);

これにより、コントローラーがサービスから更新されるときに、より慎重に微調整できます。

于 2015-10-09T16:29:51.157 に答える