有人提到我应该使用下面的真实工厂模式,所以我不必经常提供typeName
。如何在JavaScript和Angular中实现这一点。如果它是C#,我就不会有问题,但Java参考/值类型和Angular会让我的大脑受伤。
(function () {
'use strict';
angular
.module('blocks.object-cache');
objectCache.$inject = ['CacheFactory', '$auth'];
function objectCache(CacheFactory, $auth) {
var _options = {
maxAge : (60 * 60 * 1000),
deleteOnExpire : 'passive',
storageMode : 'localStorage'
};
var service = {
setOptions : setOptions,
getCache : getCache,
clear : clear,
getAll : getAll,
getItem : getItem,
getItems : getItems,
putItem : putItem,
putItems : putItems,
getItemsByKey : getItemsByKey,
getItemByKeyFirst : getItemByKeyFirst,
getItemByKeySingle : getItemByKeySingle,
removeItemsByKey : removeItemsByKey,
removeItemByKey : removeItemByKey,
putItemsByKey : putItemsByKey,
putItemByKey : putItemByKey
};
return service;
////////////////////////////////////////////////////////////////////////////////
function setOptions (options) {
options = options || {};
options.maxAge = options.maxAge = _options.maxAge;
options.deleteOnExpire = options.deleteOnExpire = _options.deleteOnExpire;
options.storageMode = options.storageMode = _options.storageMode;
_options = options;
}
function getCache(typeName) {
var cacheName = [getUserId(), normalizeTypeName(typeName || 'objects')].join('_');
var cache = CacheFactory(cacheName);
if (cache) { return cache; }
cache = CacheFactory(cacheName, _options);
return cache;
}
function clear (typeName) {
var cache = getCache(typeName);
cache.removeAll();
return (!cache.keys() || (cache.keys().length < 1));
}
function getAll (typeName) {
var cache = getCache(typeName);
var result = [];
(cache.keys() || []).forEach(function(key){
result.push(cache(key));
});
return result;
}
function getItem(typeName, id) {
if (typeof id == 'undefined' || !id.trim) { return null; }
var cache = getCache(typeName);
return cache.get(id);
}
function getItems(typeName, ids) {
var cache = getCache(typeName),
result = [],
_ids = [];
(ids || []).forEach(function(id){
if (_ids.indexOf(id) < 0) {
_ids.push(id);
var item = cache.get(id);
if (item) { result.push(item); }
}
});
return result;
}
function putItem(typeName, item, id, refresh) {
if (typeof item == 'undefined') { return false; }
if (typeof id == 'undefined' || !id.trim) { return false; }
var cache = getCache(typeName);
var existing = cache.get(id);
if (existing && !refresh) { return true; }
if (existing) { cache.remove(id); }
cache.put(item, id);
return (!!cache.get(id));
}
function putItems(typeName, items, idField, refresh) {
var cache = getCache(typeName);
(items || []).forEach(function(item){
var id = item[idField];
if (typeof id != 'undefined') {
var existing = cache.get(id);
if (existing && !!refresh) { cache.remove(id); }
if (!existing || !!refresh) { cache.put(item, id); }
if (!cache.get(id)) { return false; }
}
});
return true;
}
function getItemsByKey(typeName, key, value, isCaseSensitive) {
var result = [];
(getAll(typeName) || []).forEach(function(item){
var itemValue = item[key];
if (typeof itemValue != 'undefined') {
if ((typeof value == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || value.toLowerCase() == itemValue.toLowerCase())) {
result.push(item);
} else if (((typeof value) == (typeof itemValue)) && (value == itemValue)) {
result.push(item);
} else {
// Other scenarios?
}
}
});
return result;
}
function getItemByKeyFirst(typeName, key, value, isCaseSensitive) {
var items = getItemsByKey(typeName, key, value, isCaseSensitive) || [];
return (items.length > 0) ? items[0] : null;
}
function getItemByKeySingle(typeName, key, value, isCaseSensitive) {
var items = getItemsByKey(typeName, key, value, isCaseSensitive) || [];
return (items.length === 0) ? items[0] : null;
}
function removeItemsByKey (typeName, keyField, values, isCaseSensitive) {
var cache = getCache(typeName),
keysToRemove = [];
(cache.keys() || []).forEach(function(key){
var item = cache.get[key],
itemValue = item[keyField];
if (typeof itemValue != 'undefined') {
for (var v = 0; v < (values || []).length; v += 1) {
if ((typeof values[v] == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || values[v].toLowerCase() == itemValue.toLowerCase())) {
keysToRemove.push(key);
break;
} else if (((typeof values[v]) == (typeof itemValue)) && (values[v] == itemValue)) {
keysToRemove.push(key);
break;
} else {
// Other scenarios?
}
}
}
});
var success = true;
keysToRemove.forEach(function(key){
cache.remove(key);
if (cache.get(key)) { success = false; }
});
return success;
}
function removeItemByKey (typeName, keyField, value, isCaseSensitive) {
return removeItemsByKey(typeName, keyField, [value], isCaseSensitive);
}
function putItemsByKey(typeName, items, keyField, refresh, isCaseSensitive) {
if (!!refresh) {
var values = _.map((items || []), keyField);
if (!removeItemsByKey(typeName, keyField, values, isCaseSensitive)) { return false; }
}
var cache = getCache(typeName);
(items || []).forEach(function(item){
var id = item[keyField];
if (typeof value != 'undefined') { cache.put(item, id); }
if (!cache.get(id)) { return false; }
});
return true;
}
function putItemByKey(typeName, item, keyField, refresh, isCaseSensitive) {
return putItemsByKey(typeName, [item], keyField, refresh, isCaseSensitive);
}
function getUserId () {
return $auth.isAuthenticated() ? ($auth.getPayload().sub || 'unknown') : 'public';
}
function normalizeTypeName (typeName) {
return typeName.split('.').join('-');
}
}
})();
答案 0 :(得分:0)
我不是一个角色大师,但你不能只是移动这些功能来实现类似工厂的模式吗?我没有测试过这个,但大约有两分钟的复制粘贴...
编辑:删除了嵌套的迭代函数。
(function () {
'use strict';
angular
.module('blocks.object-cache')
.service('ObjectCache', ObjectCache);
ObjectCache.$inject = ['CacheFactory', '$auth'];
function ObjectCache(CacheFactory, $auth) {
var _options = {
maxAge : (60 * 60 * 1000),
deleteOnExpire : 'passive',
storageMode : 'localStorage'
};
var factory = {
getCache : getCache
};
return factory;
////////////////////////////
function getCache(typeName, options) {
options = options || {};
options.maxAge = options.maxAge = _options.maxAge;
options.deleteOnExpire = options.deleteOnExpire = _options.deleteOnExpire;
options.storageMode = options.storageMode = _options.storageMode;
typeName = normalizeTypeName(typeName || 'objects');
var userId = getUserId() || 'public';
var name = userId + '_' + typeName;
var service = {
type : typeName,
user : userId,
name : name,
options : options,
cache : CacheFactory(name) || CacheFactory.createCache(name, options),
clear : function () {
this.cache.removeAll();
},
getAll : function () {
var result = [];
var keys = this.cache.keys() || [];
for (var i = 0; i < keys.length; i += 1) {
result.push(this.cache(keys[i]));
}
return result;
},
getItems : function (ids) {
var result = [],
_ids = [];
for (var i = 0; i < (ids || []).length; i += 1) {
var id = ids[i];
if (_ids.indexOf(id) < 0) {
_ids.push(id);
var item = this.cache.get(id);
if (item) { result.push(item); }
}
}
return result;
},
getItem : function (id) {
var items = this.getItems([id]);
return (items.length > 0) ? items[0] : null;
},
putItem : function (item, id, refresh) {
var existing = this.cache.get(id);
if (existing && !refresh) { return true; }
if (existing) { this.cache.remove(id); }
this.cache.put(item, id);
return (!!this.cache.get(id));
},
putItems : function (items, idField, refresh) {
var success = true;
for (var i = 0; i < (items || []).length; i += 1) {
var item = items[i];
var id = item[idField];
if (typeof id != 'undefined') {
if (this.putItem(item, id, refresh)) { success = false; }
}
}
return success;
},
getItemsByKey : function (key, value, isCaseSensitive) {
var result = [];
(this.getAll() || []).forEach(function(item){
var itemValue = item[key];
if (typeof itemValue != 'undefined') {
if ((typeof value == 'string') && (typeof itemValue == 'string') && (!isCaseSensitive || value.toLowerCase() == itemValue.toLowerCase())) {
result.push(item);
} else if (((typeof value) == (typeof itemValue)) && (value == itemValue)) {
result.push(item);
} else {
// Other scenarios?
}
}
});
return result;
},
getItemByKeyFirst : function (key, value, isCaseSensitive) {
var items = this.getItemsByKey(key, value, isCaseSensitive) || [];
return (items.length > 0) ? items[0] : null;
},
getItemByKeySingle : function (key, value, isCaseSensitive) {
var items = this.getItemsByKey(key, value, isCaseSensitive) || [];
return (items.length === 0) ? items[0] : null;
},
removeItemsByKey : function (keyField, values, isCaseSensitive) {
var keysToRemove = [],
keys = this.cache.keys() || [];
for (var k = 0; k < keys.length; k += 1) {
var key = keys[k];
var item = this.cache.get(key);
var itemVal = item[keyField];
if (typeof itemVal != 'undefined') {
for (var v = 0; v < (values || []).length; v += 1) {
if ((typeof values[v] == 'string') && (typeof itemVal == 'string') && (!isCaseSensitive || values[v].toLowerCase() == itemVal.toLowerCase())) {
keysToRemove.push(key);
break;
} else if (((typeof values[v]) == (typeof itemVal)) && (values[v] == itemVal)) {
keysToRemove.push(key);
break;
} else {
// Other scenarios?
}
}
}
}
var success = true;
for (var r = 0; r < keysToRemove.length; r += 1) {
this.cache.remove(keysToRemove[r]);
if (this.cache.get(keysToRemove[r])) { success = false; }
}
return success;
},
removeItemByKey : function (keyField, value, isCaseSensitive) {
return this.removeItemsByKey(keyField, [value], isCaseSensitive);
},
putItemsByKey : function(items, keyField, refresh, isCaseSensitive) {
if (!!refresh) {
var values = _.map((items || []), keyField);
if (!this.removeItemsByKey(keyField, values, isCaseSensitive)) { return false; }
}
for (var i = 0; i < (items || []).length; i += 1) {
var id = items[i][keyField];
if (typeof id != 'undefined') {
this.cache.put(items[i], id);
if (!this.cache.get(id)) { return false; }
}
}
return true;
},
putItemByKey : function (item, keyField, refresh, isCaseSensitive) {
return this.putItemsByKey([item], keyField, refresh, isCaseSensitive);
}
};
return service;
}
function getUserId () {
return $auth.isAuthenticated() ? ($auth.getPayload().sub || 'unknown') : null;
}
function normalizeTypeName (typeName) {
return typeName.split('.').join('-');
}
}
})();