如何有效地存储/检索chrome.storage.sync中的数据?

时间:2013-06-19 20:18:22

标签: google-chrome-extension local-storage

所以,我正在编写一个扩展程序,允许人们从Web上的图像中精确保存颜色。它进展顺利,但现在我试图概念化我将如何实际存储它们,并列出存储的项目。

据我所知,chrome.storage.sync()只允许使用对象。这意味着我必须做这样的事情:

{colors: [{colorName: 'white', colorHex: '#ffffff'}, {colorName: 'black', colorHex: '#000000'}]}

这看起来非常低效,因为每次我想从收藏列表中添加或减去颜色时,我都需要获取整个数组,更改我想要的一个项目,然后将数据存储回来。更不用说扫描一个颜色的数组,看它是否存在可能是一个大阵列上非常密集的。

最终,我希望能够按照

的方式做点什么
 colors['#fff'].name = white;

然而,这似乎不可能。

我很想听听其他一些想法,了解实现这一目标的最佳方式。

2 个答案:

答案 0 :(得分:8)

Javascript的魅力在于,一切都被认为是一个对象。函数,数组甚至变量都可以作为对象访问。

您可以创建一个这样的数组,

var colors {}
colors["#FFF"] = "white";
colors["#000"] = "black";

或许可以使用一个空函数数组,

function color(name, hex /* ... other properties */ ) { }

var colors {
    color1: color("white", "#FFF");
    color2: color("black", "#000");
}

然后可以通过

访问这些颜色
color1.name

color1.hex

虽然,因为您应该为存储中的每个对象使用特定的“键”值,这可能是更好的方法。

例如,

function save_color() {
    var white = "#FFF";
                             //key    value   callback
    chrome.storage.sync.set({"white": white}, function() {
        console.log("The value stored was: " + white);
    });
}

或者,对于多种颜色

function save_colors() {
    var white = "#FFF";
    var black = "#000";

    chrome.storage.sync.set([{"white": white}, {"black": black}], function() {
        console.log("The values stored are: " + white + " and " + black);
    });
}

我认为这可行,我之前没有尝试使用一个api调用存储多个对象,但你应该明白这一点。实现这一点的一个好方法可能是在每次用户找到想要添加的颜色时添加一个空数组,然后定期扩展可以将数据推送到同步。

完成大量测试并且同步存储混乱后,请跟踪开发过程中使用的密钥,并记住运行批量数据删除。它看起来像这样:

function clear_data() {
    var keys = { "white", "black" };
    chrome.storage.sync.remove(keys, function() {
        for(var i = 0; i < keys.length; i++)
            console.log("Removed Data for Key: " + key[i]);
    });
}

顺便说一句,要检索存储在同步中的值,

function load_color() {
    var color = "white";
                           //key   callback
    chrome.storage.sync.get(color, function(val) {
        console.log("The value returned was: " + val);
    });
}

答案 1 :(得分:2)

我也不确定这一点,所以我做了一个小例子。

<强> manifest.json:

{
    "manifest_version": 2,

    "name": "Test",
    "description": "Test.",
    "version": "1.0",

    "permissions": [
        "storage"
    ],
    "content_scripts": [
        {
            "matches": ["https://www.google.com/*"],
            "js": ["content-script.js"]
        }
    ]
}

<强> content-script.js:

console.log("content script loaded")

function modifyObject() {
    chrome.storage.sync.get(null, function(storageData3) {
        storageData3.object.property2 = false;

        chrome.storage.sync.set(storageData3, function() {
            chrome.storage.sync.get(null, function(storageData4) {
                console.log("after setting *only* object: " + JSON.stringify(storageData4));
            });
        });
    });
}

// Dumb attempt at setting only property2 of "object"; will add a new top level object "property2".
function attemptToModifyProperty2() {
    var toSave = { "property2": false };
    chrome.storage.sync.set(toSave, function() {
        chrome.storage.sync.get(null, function(storageData2) {
            console.log("after attemping to set *only* property2: " + JSON.stringify(storageData2));

            modifyObject();
        });
    });
}

function addArray() {
    var toSave = { "array": [1, 2, 3] };
    chrome.storage.sync.set(toSave, function() {
        chrome.storage.sync.get(null, function(storageData1) {
            console.log("after setting *only* array: " + JSON.stringify(storageData1));

            attemptToModifyProperty2();
        });
    });
}

function addObject() {
    var toSave = { "object": { "property1": true, "property2": true } };
    chrome.storage.sync.set(toSave, function() {
        chrome.storage.sync.get(null, function(storageData) {
            console.log("after setting *only* object: " + JSON.stringify(storageData));

            addArray();
        });
    });
}

chrome.storage.sync.clear();

addObject();

如果您访问google.com(并登录,或将matches中的manifest.json更改为http),然后打开控制台,您就会看到此信息输出:

content script loaded
content-script.js:42 after setting *only* object: {"object":{"property1":true,"property2":true}}
content-script.js:31 after setting *only* array: {"array":[1,2,3],"object":{"property1":true,"property2":true}}
content-script.js:20 after attemping to set *only* property2: {"array":[1,2,3],"object":{"property1":true,"property2":true},"property2":false}
content-script.js:9 after setting *only* object: {"array":[1,2,3],"object":{"property1":true,"property2":false},"property2":false}

我的结论是,它只能设置顶级对象。即使您只想更改嵌套在顶级对象中的一个属性,也必须将整个对象传递给set()