Resolve a function and use its side effect to record data in a service

I am making a web page with ui-router . Before we enter the controller, I want some operations to be done: 1) create a temporary folder in the server and write some files; 2) record the name of the folder and some other data. So naturally I choose to use resolve .

.state('panels', {
    controller: 'PanelsCtrl',
    resolve: {
        init: ['codeService', function (codeService) {
            return codeService.init()
        }]
    },
    ...
});

app.service('codeService', ['$http', function ($http) {
    var srcP = "default" // private variable
    this.getSrcP = function () { return srcP };

    this.init = function () {
        return $http.post("/writeFiles", ...) // write files in a temporary folder of the server
            .then(function (res) {
                srcP = res.data;
                return srcP
            }
    }
};

app.controller('PanelsCtrl', ['$scope', 'codeService', 'init', function($scope, codeService, init) {
    $scope.src = codeService.getSrcP();
    ...
}

The above code works. However, I feel odd about 1) I resolve an asynchronous function (ie, init ) rather than data (that people usually resolve); 2) I use a side effect of init to record data (ie, srcP ) in a service .

It seems that, in comparaison with resolving data, it is easier when we have more data to be recorded, we just need to have more private variables and make more side effects in the service.

Does anyone know if what I do is a bad/common/good practice? Additionally, why codeService in resolve: {...} and codeService injected to PanelsCtrl share same private variables?


I think that's a better approach if you clean up the service and don't resolve the promise inside it.
You can let UI-ROUTER to resolve the promise and inject the result data in the controller...

.state('panels', {
    controller: 'PanelsCtrl',
    resolve: {
        init: ['codeService', function (codeService) {
            return codeService.init()
        }]
    }
});

app.service('codeService', ['$http', function ($http) {
    this.init = function () {
        return $http.post("/writeFiles");
    }
};

app.controller('PanelsCtrl', ['$scope', 'init', function($scope, init) {
    $scope.src = init; //init is the resolved data of codeService...
}

I've just made an example. Check this jsFiddle.


I think theoretically there's nothing wrong causing side effects in resolve, that's what it's there for. Take Restangular as an example. You keep calling for resources in resolve, the cacheing is handled by Restangular, which is basically a side effect.

However, I see some problems with the server-side approach. Storing files on the server is usually a bad idea (think about scaling/compromised immutability of the infrastructure). So I'd rather utilize the DB for this, and you could turn your folder abstraction to a DB resource.

链接地址: http://www.djcxy.com/p/77998.html

上一篇: AngularJS和IE 8服务错误

下一篇: 解析一个函数并使用其副作用来记录服务中的数据