1. ホーム
  2. angularjs

サービスデータ変更時のスコープ値更新

2023-08-31 11:13:46

質問

私のアプリには、以下のようなサービスがあります。

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 .

私のテンプレートでは空のままです。この変更をどのように反映させるかご存知ですか?

どのように解決するのですか?

を使用しているときに $watch を使うことで問題は解決するかもしれませんが、最も効率的な解決策とは言えません。サービス内のデータを保存する方法を変更したほうがよいでしょう。

この問題は、あなたの taskList が関連付けられているメモリの場所を、新しい値を代入するたびに置き換えていることです。この現象は このプランク .

最初に plunk を読み込んだときに Chrome でヒープスナップショットを取り、ボタンをクリックした後、リストが異なるメモリロケーションを指している間、スコープが指すメモリロケーションが決して更新されないことがわかります。

変更される可能性のある変数を含むオブジェクトをサービスに保持させることで、簡単にこれを修正することができます (たとえば data:{task:[], x:[], z:[]} ). この場合、quot;data" は決して変更されるべきではありませんが、そのメンバーは必要なときにいつでも変更することができます。そして、この data 変数をスコープに渡すと、 "data" を他のものに代入して上書きしない限り、 data 内のフィールドが変更されると、スコープはそれを知っていて正しく更新されます。

このplunkは は、上で提案した修正を使って同じ例を実行しています。この状況ではウォッチャーを使う必要はありませんし、もしビュー上で何かが更新されないということが起こっても、必要なのはスコープを実行することだけです。 $apply を実行してビューを更新すればよいのです。

この方法では、変数の変更を頻繁に比較するウォッチャーや、多くの変数を監視する必要がある場合の面倒なセットアップが必要なくなります。この方法の唯一の問題は、ビュー (html) 上で、以前は変数名だけだったところに "data." がすべての接頭辞として付くことです。