具有数据库 API 接口的 Chrome 扩展程序

发布于 2024-11-17 11:17:22 字数 3940 浏览 5 评论 0原文

我想用从 chrome 本地数据库生成的锚点列表更新 div。这是非常简单的事情,但是当我尝试通过回调将数据添加到 main.js 文件时,一切都突然变得不确定。或者将数组长度设置为 0。(当它实际上是 18 时。)

最初,我尝试将其安装到一个新数组中并以这种方式将其传回。

我是否需要在 chrome manifest.json 中指定一个设置才能与数据库 API 进行通信?我已经检查过,但我所能找到的只是“无限存储”

代码如下:

    window.main = {};
window.main.classes = {};
(function(awe){
    awe.Data = function(opts){
      opts = opts || new Object();
      return this.init(opts);
    };
    awe.Data.prototype = {
        init:function(opts){
            var self = this;
            self.modified = true;

            var db = self.db = openDatabase("buddy","1.0","LocalDatabase",200000);
            db.transaction(function(tx){
                tx.executeSql("CREATE TABLE IF NOT EXISTS listing ( name TEXT UNIQUE, url TEXT UNIQUE)",[],function(tx,rs){
                    $.each(window.rr,function(index,item){
                        var i = "INSERT INTO listing (name,url)VALUES('"+item.name+"','"+item.url+"')";
                        tx.executeSql(i,[],null,null);
                    });
                },function(tx,error){

                });
            });
            self._load()
            return this;
        },
        add:function(item){
            var self = this;
            self.modified = true;
            self.db.transaction(function(tx){
                tx.executeSql("INSERT INTO listing (name,url)VALUES(?,?)",[item.name,item.url],function(tx,rs){
                    //console.log('success',tx,rs)
                },function(tx,error){
                    //console.log('error',error)
                })
            });
            self._load()
        },
        remove:function(item){
            var self = this;
            self.modified = true;
            self.db.transaction(function(tx){
                tx.executeSql("DELETE FROM listing where name='"+item.name+"'",[],function(tx,rs){
                    //console.log('success',tx,rs)
                },function(tx,error){
                    //console.log('error',tx,error);
                });
            });
            self._load()
        },
        _load:function(callback){
            var self = this;
            if(!self.modified)
                return;
            self.data = new Array();
            self.db.transaction(function(tx){
                tx.executeSql('SELECT name,url FROM listing',[],function(tx,rs){
                    console.log(callback)
                    for(var i = 0; i<rs.rows.length;i++)
                    {

                        callback(rs.rows.item(i).name,rs.rows.item(i).url)
                        // var row = rs.rows.item(i)
                        // var n = new Object()
                        // n['name'] = row['name'];
                        // n['url'] = row['url'];
                    }
                },function(tx,error){
                    //console.log('error',tx,error)
                })
            })
            self.modified = false
        },
        all:function(cb){
            this._load(cb)
        },
        toString:function(){
            return 'main.Database'
        }
    }
})(window.main.classes);

以及更新列表的代码。

this.database.all(function(name,url){
       console.log('name','url')
       console.log(name,url)

       var data = []
       $.each(data,function(index,item){
           try{
               var node = $('<div > <a href="'+item.url+'">'+item.name + '</a></div>');
               self.content.append(node);
               node.unbind();
               node.bind('click',function(evt){
                   var t = $(evt.target).attr('href');
                   chrome.tabs.create({
                       "url":t
                   },function(evt){
                       self._tab_index = evt.index
                   });
               });
           }catch(e){
               console.log(e)
           }
       })    
   });

I want to update a div with a list of anchors that I generate from a local database in chrome. It's pretty simple stuff, but as soon as I try to add the data to the main.js file via a callback everything suddenly becomes undefined. Or the array length is set to 0. ( When it's really 18. )

Initially, I tried to install it into a new array and pass it back that way.

Is there a setting that I need to specify in the chrome manifest.json in order to allow for communication with the database API? I've checked, but all I've been able to find was 'unlimited storage'

The code is as follows:

    window.main = {};
window.main.classes = {};
(function(awe){
    awe.Data = function(opts){
      opts = opts || new Object();
      return this.init(opts);
    };
    awe.Data.prototype = {
        init:function(opts){
            var self = this;
            self.modified = true;

            var db = self.db = openDatabase("buddy","1.0","LocalDatabase",200000);
            db.transaction(function(tx){
                tx.executeSql("CREATE TABLE IF NOT EXISTS listing ( name TEXT UNIQUE, url TEXT UNIQUE)",[],function(tx,rs){
                    $.each(window.rr,function(index,item){
                        var i = "INSERT INTO listing (name,url)VALUES('"+item.name+"','"+item.url+"')";
                        tx.executeSql(i,[],null,null);
                    });
                },function(tx,error){

                });
            });
            self._load()
            return this;
        },
        add:function(item){
            var self = this;
            self.modified = true;
            self.db.transaction(function(tx){
                tx.executeSql("INSERT INTO listing (name,url)VALUES(?,?)",[item.name,item.url],function(tx,rs){
                    //console.log('success',tx,rs)
                },function(tx,error){
                    //console.log('error',error)
                })
            });
            self._load()
        },
        remove:function(item){
            var self = this;
            self.modified = true;
            self.db.transaction(function(tx){
                tx.executeSql("DELETE FROM listing where name='"+item.name+"'",[],function(tx,rs){
                    //console.log('success',tx,rs)
                },function(tx,error){
                    //console.log('error',tx,error);
                });
            });
            self._load()
        },
        _load:function(callback){
            var self = this;
            if(!self.modified)
                return;
            self.data = new Array();
            self.db.transaction(function(tx){
                tx.executeSql('SELECT name,url FROM listing',[],function(tx,rs){
                    console.log(callback)
                    for(var i = 0; i<rs.rows.length;i++)
                    {

                        callback(rs.rows.item(i).name,rs.rows.item(i).url)
                        // var row = rs.rows.item(i)
                        // var n = new Object()
                        // n['name'] = row['name'];
                        // n['url'] = row['url'];
                    }
                },function(tx,error){
                    //console.log('error',tx,error)
                })
            })
            self.modified = false
        },
        all:function(cb){
            this._load(cb)
        },
        toString:function(){
            return 'main.Database'
        }
    }
})(window.main.classes);

And the code to update the list.

this.database.all(function(name,url){
       console.log('name','url')
       console.log(name,url)

       var data = []
       $.each(data,function(index,item){
           try{
               var node = $('<div > <a href="'+item.url+'">'+item.name + '</a></div>');
               self.content.append(node);
               node.unbind();
               node.bind('click',function(evt){
                   var t = $(evt.target).attr('href');
                   chrome.tabs.create({
                       "url":t
                   },function(evt){
                       self._tab_index = evt.index
                   });
               });
           }catch(e){
               console.log(e)
           }
       })    
   });

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

可爱暴击 2024-11-24 11:17:22

通过查看上面的代码,我注意到您正在 API 中每个函数的末尾执行“self._load()”。 HTML5 SQL 数据库是异步的,您永远无法保证结果。在这种情况下,我假设结果将始终为 0 或随机,因为这将是竞争条件。

我在我的 fb-exporter 扩展中做了类似的事情,请随意看看我是如何做到的 https://github.com/mohamedmansour/fb-exporter/blob/master/js/database.js

要解决这样的问题,您是否检查了 Web Inspector并查看后台页面是否出现错误。我认为这一切都在后台页面中,是吗?尝试查看是否发生任何错误,如果没有,我相信您遇到了竞争条件。只需在回调中移动负载,它就应该正确调用负载。

关于您关于无限存储清单属性的第一个问题,在这种情况下您不需要它,这不应该是问题。 Web 数据库的限制是 5MB(最后我记得,它可能已经改变),如果您使用大量数据操作,那么您可以使用该属性。

只需确保您可以保证 this.database.all 在数据库初始化后运行。

From looking at your code above, I notice you are executing "self._load()" at the end of each function in your API. The HTML5 SQL Database is asynchronous, you can never guarantee the result. In this case, I would assume the result will always be 0 or random because it will be a race condition.

I have done something similar in my fb-exporter extension, feel free to see how I have done it https://github.com/mohamedmansour/fb-exporter/blob/master/js/database.js

To solve a problem like this, did you check the Web Inspector and see if any errors occurs in the background page. I assume this is all in a background page eh? Try to see if any error occurs, if not, I believe your encountering a race condition. Just move the load within the callback and it should properly call the load.

Regarding your first question with the unlimited storage manifest attribute, you don't need it for this case, that shouldn't be the issue. The limit of web databases is 5MB (last I recall, it might have changed), if your using a lot of data manipulation, then you use that attribute.

Just make sure you can guarantee the this.database.all is running after the database has been initialized.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文