Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/asp.net-core/3.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Google chrome extension 如何在chrome.storage.sync中高效地存储/检索数据?_Google Chrome Extension_Local Storage - Fatal编程技术网

Google chrome extension 如何在chrome.storage.sync中高效地存储/检索数据?

Google chrome extension 如何在chrome.storage.sync中高效地存储/检索数据?,google-chrome-extension,local-storage,Google Chrome Extension,Local Storage,因此,我正在编写一个扩展,允许人们从网络上找到的图像中筛选和保存颜色。它进行得很顺利,但现在我正在尝试概念化如何实际存储它们,并列出存储的项 据我所知,chrome.storage.sync()只允许对象。这意味着我必须做这样的事情: {colors: [{colorName: 'white', colorHex: '#ffffff'}, {colorName: 'black', colorHex: '#000000'}]} function clear_data() { var ke

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

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

{colors: [{colorName: 'white', colorHex: '#ffffff'}, {colorName: 'black', colorHex: '#000000'}]}
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]);
    });
}
这似乎非常低效,因为每次我想从收藏夹列表中添加或减去颜色时,我都需要获取整个数组,更改我想要的一个项目,然后将数组存储回原处。更不用说扫描阵列以查看颜色是否存在,在大型阵列上可能会非常密集

最终,我希望能够按照

 colors['#fff'].name = white;
然而,这似乎是不可能的


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

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

尽管如此,因为您应该为存储中的每个对象使用特定的“键”值,所以这可能是一种更好的方法

比如说,

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调用存储多个对象,但您应该明白这一点。实现这一点的一个好方法可能是在用户每次找到想要添加的颜色时都添加一个空数组,然后扩展可以周期性地推送数据进行同步

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

{colors: [{colorName: 'white', colorHex: '#ffffff'}, {colorName: 'black', colorHex: '#000000'}]}
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]);
    });
}

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

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"]
        }
    ]
}
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();
content script.js:

{
    "manifest_version": 2,

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

    "permissions": [
        "storage"
    ],
    "content_scripts": [
        {
            "matches": ["https://www.google.com/*"],
            "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(登录,或将
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()

此外,如果您决定添加使用本地存储而不是同步的选项,或者两者的组合,则chrome.storage.local的语法与chrome.storage.sync相同。允许用户决定他们想要什么类型的存储通常是一种好的做法(有些人不喜欢云)。