繁体   English   中英

尝试在AngularJS工厂内返回局部变量时,如何避免使用函数表达式?

[英]How do I avoid a function expression when trying to return a local variable within an AngularJS factory?

如何通过发出“ vm.stories = storyDataAsFactory.stories”与现在执行的操作“ vm.stories = storyDataAsFactory.stories()”来返回“ stories”? 我尝试了所有可能的组合,但均未成功。 此外,我可以在不带括号的情况下调用storyDataAsFactory.getStories,这基于我的配置方式是有意义的,但是当我创建一个返回self.stories的函数时,它将不起作用。

以下代码按指定方式工作-

storyDataAsFactory.$inject = ['$http', '$q'];

angular.module('ccsApp').factory('storyDataAsFactory', storyDataAsFactory);

function storyDataAsFactory($http, $q) {
    var self = this;
    var stories = [];

    function getStories(url) {
        url = url || '';

        var deferred = $q.defer();

        $http({method: 'GET', url: url})
            .success(function (data, status, headers, config) {
                self.stories = data;

                deferred.resolve(data);
            })
            .error(function (data, status, headers, config) {
                deferred.reject(status);
            });

        return deferred.promise;
    }

    function listStories() {
        return self.stories;
    }

    return {
        stories: listStories,

        getStories: getStories('stories.json')
    };
}

更新:

我仍然有问题。 这是我的确切代码,我根据社区进行了更改-

storyDataAsFactory.$inject = ['$http', '$q'];

angular.module('ccsApp').factory('storyDataAsFactory', storyDataAsFactory);

function storyDataAsFactory($http, $q) {
    var stories = [];

    function getStories(url) {
        url = url || '';

        if (url !== '') {
            var deferred = $q.defer();

            //determine if ajax call already occurred;
            //if so, data exists in cache as local var
            if (stories.length !== 0) {
                deferred.resolve();
                return deferred.promise;
            }

            $http({method:'GET', url:url})
                .success(function (data, status, headers, config) {
                    stories = data;

                    deferred.resolve();
                })
                .error(function (data, status, headers, config) {
                    deferred.reject(status);
                });

            return deferred.promise;
        } else {
            alert('URL was empty.');
        }
    }

    return {
        stories: stories,

        getStories: function(url) {
            getStories(url);
        }
    };
}

storyDataAsFactory.stories不返回任何内容。 请记住,我确保解析会正确触发,因此这不是异步的。 问题。 我就是不明白这一点! 我已经花了几个小时没有成功。

我认为您对Angular服务和工厂概念感到困惑:

下面让我们讨论一下:

角度服务:

module.service( 'serviceName', function );
Result: When declaring serviceName as an injectable argument you will be provided
        with the instance of a function passed to module.service.

角工厂

module.factory( 'factoryName', function );
Result: When declaring factoryName as an injectable argument you will be provided
        the value that is returned by invoking the function reference passed to
        module.factory. So if you want to access the methods of that factory then
        they should be there along with returned value.

您给定代码的Angular服务版本为:

schoolCtrl.service('storyDataAsService', storyDataAsService);

function storyDataAsService($http, $q) {
    var self = this;
    var stories = [];

    this.getStories = function(url) {
        url = url || '';

        var deferred = $q.defer();

        $http({method: 'GET', url: url})
            .success(function (data, status, headers, config) {
                self.stories = data;

                deferred.resolve(data);
            })
            .error(function (data, status, headers, config) {
                deferred.reject(status);
            });

        return deferred.promise;
    };
    this.stories = function(){
        // @TODO return value
    }
}

Angular的出厂版本:

storyDataAsFactory.$inject = ['$http', '$q'];

angular.module('ccsApp').factory('storyDataAsFactory', storyDataAsFactory);

function storyDataAsFactory($http, $q) {
    var self = this;
    var stories = [];

    function getStories(url) {
        url = url || '';

        var deferred = $q.defer();

        $http({method: 'GET', url: url})
            .success(function (data, status, headers, config) {
                self.stories = data;

                deferred.resolve(data);
            })
            .error(function (data, status, headers, config) {
                deferred.reject(status);
            });

        return deferred.promise;
    }

    return {
        stories: function() {
            // @TODO return value
        },

        getStories: getStories
    };
}

在您的情况下, self是工厂storyDataAsFactoryProvider提供者。 但是您需要使用局部变量stroies ,而不是提供程序对象字段self.stroies 我已修复您的错误。 现在可以了。

UPD:如果要使用stories作为字段而不是getter,则不能更改局部变量(对原始数组的引用)。 您只能修改原始数组。

 storyDataAsFactory.$inject = ['$http', '$q']; angular.module('ccsApp', /*XXX added []*/[]).factory('storyDataAsFactory', storyDataAsFactory); function storyDataAsFactory($http, $q) { var stories = []; function getStories(url) { url = url || ''; if (url !== '') { var deferred = $q.defer(); //determine if ajax call already occurred; //if so, data exists in cache as local var if (stories.length !== 0) { deferred.resolve(); return deferred.promise; } $http({method:'GET', url:url}) .success(function (data, status, headers, config) { // XXX using this code you lose original array //stories = data; // XXX instead you need to clear and to fill original array stories.splice(0, stories.length); data.forEach(function(x) { stories.push(x); }); deferred.resolve(); }) .error(function (data, status, headers, config) { deferred.reject(status); }); return deferred.promise; } else { alert('URL was empty.'); } } return { stories: stories, // XXX using field instead of getter you need to keep original array getStories: function(url) { getStories(url); } }; } // ------------ tests -------------------- describe('storyDataAsFactory.stories()', function() { var $httpBackend, $http, $q, storyDataAsFactory; beforeEach(module('ccsApp')); beforeEach(inject(function(_$httpBackend_) { $httpBackend = _$httpBackend_; $httpBackend.whenGET('stories.json').respond([1, 2, 3]); })); beforeEach(inject(function(_$http_, _$q_, _storyDataAsFactory_) { $http = _$http_; $q = _$q_; storyDataAsFactory = _storyDataAsFactory_; })); it('should return empty array before ajax resolved', function() { storyDataAsFactory.getStories('stories.json'); expect(storyDataAsFactory.stories).toEqual([]); $httpBackend.flush(); }); it('should return filled array after ajax resolved', function() { storyDataAsFactory.getStories('stories.json'); $httpBackend.flush(); expect(storyDataAsFactory.stories).toEqual([1, 2, 3]); }); }); // ------------ run tests -------------------- window.onload = function() { var jasmineEnv = jasmine.getEnv(); var htmlReporter = new jasmine.HtmlReporter(); jasmineEnv.addReporter(htmlReporter); jasmineEnv.execute(); }; 
 <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/1.3.1/jasmine.js"></script> <link href="https://cdnjs.cloudflare.com/ajax/libs/jasmine/1.3.1/jasmine.css" rel="stylesheet"/> <script src="https://cdnjs.cloudflare.com/ajax/libs/jasmine/1.3.1/jasmine-html.js"></script> <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script> <script src="https://cdnjs.cloudflare.com/ajax/libs/angular.js/1.2.28/angular-mocks.js"></script> 

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM