9

因此,我正在编写一个扩展程序,以允许人们从网络上找到的图像中微调和保存颜色。进展顺利,但现在我正在尝试概念化我将如何实际存储它们,并列出存储的项目。

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

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

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

最终,我希望能够按照以下方式做一些事情

 colors['#fff'].name = white;

然而,这似乎是不可能的。

我很想听听其他一些关于实现这一目标的最佳方法的想法。

4

2 回答 2

9

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);
    });
}
于 2013-06-19T21:04:19.570 回答
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(并登录,或将matchesin更改manifest.jsonhttp),然后打开控制台,您将看到以下输出:

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().

于 2015-07-26T09:29:19.487 回答