我有一个回答“Widgets”的网络服务,每个都有一大堆简单的对象,“部分”,需要单独提取。我希望将此作为一个角度服务公开,它提取小部件 - 以及其中一些部分 - 并将结果缓存在localStorage中,但我遇到了问题(在代码中注明,然后在下面)...
angular.module('myApp').service('myWidgetService', function ($q, requestService, localStorageService, _) {
// start everything off by fetching the Widgets, saving locally
this.refresh = function() {
var self = this;
return requestService.request('GET', '/api/widget/', true).then(function(result) {
self.setCloudArray(result);
// I want callers to use "Widget instances" defined below
return _.map(result, function(cloudItem) { return new Widget(cloudItem); });
});
};
// get and set persistent widget array
this.cloudArray = function() {
return localStorageService.get('cloudArray');
};
this.setCloudArray = function(cloudArray) {
localStorageService.set('cloudArray', cloudArray);
};
// I want this "Widget instance" to provide methods related to a single widget
var Widget = function(cloudItem) {
this.cloudItem = cloudItem; // PROBLEM A: (this indirection hurts me later)
};
// get the parts, but only if they haven't been fetched already
// if they've been fetched, return the cached copy
Widget.prototype.parts = function() {
var self = this.cloudItem; // weirdness due to PROBLEM A
if (self.parts) { return $q.when(self.parts); }
var route = '/api/widget/' + self._id + '/parts';
return requestService.request('GET', route, true).then(function(result) {
self.parts = result; // PROBLEM B: how to persist?
return result;
});
};
Widget.prototype.partWithId = function(id) {
return _.find(this.cloudItem.parts, function(part) { return part._id === id; });
};
});
我在代码中标记了我遇到的两个问题。
问题A:我真的不想在我的Widget中添加一个cloudItem属性。在窗口小部件方法中,我想对对象的this.foo
属性说foo
之类的内容,但我不得不说this.cloudItem.foo
。
问题B:更大的问题是对小部件的调用是昂贵的,我想缓存结果。但是本地存储知道的是我的实例“cloudItem”所属的对象数组。我不知道在我的widget对象中保存的优雅方法。
我在类级别编写了一个不太优雅的方法来更新本地存储:
this.saveWidget = function(updatedWidget) {
var cloudArray = this.cloudArray();
var currentItem = _.find(cloudArray, function(i) { return i._id === updatedWidget._id; });
var index = cloudArray.indexOf(currentItem);
cloudArray[index] = updatedWidget;
this.setCloudArray(cloudArray);
};
取出零件后我打电话给我。这很有效,但是虽然我对JS和Web开发没有太多经验,但我知道我已经把自己挖到了一个洞里。我已经阅读了很多关于服务和JS对象的东西,但很明显我错过了一些重要的东西。
如何避免我的Widget对象中的额外间接,并为其提供更直接,更OO的方式将自己保存到本地存储?
提前感谢您的帮助。
答案 0 :(得分:0)
我学到了两件帮助我解决这个问题的事情:angular.extend()
解决了我的第一个问题......
var Widget = function(cloudItem) {
angular.extend(this, cloudItem);
// replaces
// this.cloudItem = cloudItem; // PROBLEM A: (this indirection hurts me later)
};
感谢extend()(以及返回'this'的隐藏魔法),我不需要'cloudItem'属性。
在我的第二个问题中,我失去了试图在对象级别保存状态。我想我必须忍受节约发生在班级的事实。
我使用对象级保存方法改进了一些东西(并且保留了索引对象而不是数组,这得益于@charlietfl的建议)
// replaces the awkward: this.saveWidget = function(updatedWidget) I had before
Widget.prototype.save = function() {
var cloudArray = localStorageService.get('cloudArray');
// really a cloud object, thanks to suggestion by @charlietfl
cloudArray[this._id] = this;
localStorageService.set('cloudArray', cloudArray);
};
至少我可以假装save()对我有意义。实例上的这个方法隐藏了(丑陋的,imo)事实,即在类级别上保存真的很糟糕。
Javascript很奇怪。