我如何回归"故事"发出" vm.stories = storyDataAsFactory.stories"与我现在所做的相比,这是" vm.stories = storyDataAsFactory.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不会返回任何内容。请记住,我接着已经解决了适当的解决方案,所以这不是异步。问题。我只是没有得到这个!我已经好几个小时没有成功了。
答案 0 :(得分:0)
我认为你对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.
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
}
}
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
};
}
答案 1 :(得分:0)
在您的情况下,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>
&#13;