使用$timeout等待服务数据解析

Use $timeout to wait service data resolved

本文关键字:数据 服务 等待 timeout 使用      更新时间:2023-09-26

我正在尝试通过服务将数据从指令传递到控制器,我的服务如下所示:

angular
    .module('App')
    .factory('WizardDataService', WizardDataService);
WizardDataService.$inject = [];
function WizardDataService() {
    var wizardFormData = {};
    var setWizardData = function (newFormData) {
        console.log("wizardFormData: " + JSON.stringify(wizardFormData));
        wizardFormData = newFormData;
    };
    var getWizardData = function () {
        return wizardFormData;
    };
    var resetWizardData = function () {
        //To be called when the data stored needs to be discarded
        wizardFormData = {};
    };
    return {
        setWizardData: setWizardData,
        getWizardData: getWizardData,
        resetWizardData: resetWizardData
    };
}

但是当我尝试从控制器获取数据时,它没有解决(我认为它等待摘要循环完成),所以我必须在控制器中使用$timeout函数来等待它完成,如下所示:

$timeout(function(){
    //any code in here will automatically have an apply run afterwards
    vm.getStoredData = WizardDataService.getWizardData();
    $scope.$watchCollection(function () {
        console.log("getStoredData callback: " + JSON.stringify(vm.getStoredData));
        return vm.getStoredData;
    }, function () {
    });
}, 300);

尽管它有效,但我感兴趣的是,如果有更好的方法来做到这一点,如果这是无错误的和主要问题,为什么我们使用 300 延迟而不是 100(例如)进行$timeout以及它是否总是有效(也许对于某人来说,从服务获取数据花费的时间超过 300 年)。

您可以从服务 get 方法返回承诺。 然后在控制器中,可以提供成功方法来分配结果。 您的服务如下所示:

    function getWizardData() {
        var deferred = $q.defer();
        $http.get("/myserver/getWizardData")
            .then(function (results) {
                deferred.resolve(results.data);
            }),
            function () {
                deferred.reject();
            }
        return deferred.promise;
    }

在 ng 控制器中,您可以调用您的服务:

wizardService.getWizardData()
     .then(function (results) {
        $scope.myData = results;
     },
     function () { });

无需超时。 如果您的服务器是 RESTFULL,则使用 $resource 并直接绑定。

使用 angular.copy 替换数据而不更改对象引用。

function WizardDataService() {
    var wizardFormData = {};
    var setWizardData = function (newFormData) {
        console.log("wizardFormData: " + JSON.stringify(wizardFormData));
        angular.copy(newFormData, wizardFormData);
    };

从文档中:

角度复制

创建源的深层副本,该副本应为对象或数组。

  • 如果提供了目标,则会删除其所有元素(对于数组)或属性(对于对象),然后将源中的所有元素/属性复制到该目标。

用法

 angular.copy(source, [destination]);

-- AngularJS angular.copy API 参考

这样,对象引用将保持不变,并且具有该引用的任何客户端都将得到更新。无需在每次更新时获取新的对象引用。