Chrome扩展与数据库API接口 [英] Chrome Extension with Database API interface

查看:99
本文介绍了Chrome扩展与数据库API接口的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想用我在chrome中从本地数据库生成的锚点列表更新div。这是非常简单的东西,但只要我尝试通过回调将数据添加到main.js文件,所有内容突然变得不确定。或者数组长度设置为0.(当它真的是18)。

最初,我试图将它安装到一个新的数组中并将其传回。 / p>

是否有需要在chrome manifest.json中指定的设置以允许与数据库API进行通信?我已经检查过了,但我所能找到的所有内容都是'无限存储'。



代码如下:

  window.main = {}; 
window.main.classes = {};
(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 list(name,url)VALUES('+ item.name +','+ item.url +');
tx.executeSql(i,[],null,null );
});
},函数(tx,error){

});
});
self._load()
返回此;
},
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],函数(tx,rs){
//console.log('success',tx,rs)
},函数(tx,error){
//console.log('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)
},函数(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回调)
for(var i = 0; 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);

以及更新列表的代码。



< pre $ this.database.all(函数(名称,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
});
$ b});
} catch(e){
console.log(e)
}
})
});


解决方案

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



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

为了解决这个问题,你检查了Web Inspector和看看是否有任何错误发生在后台页面。我认为这是全部在后台页面呃?试着看看是否有错误发生,如果没有,我相信你遇到了一个竞争条件。



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



确保你可以保证在数据库初始化之后 this.database.all 正在运行。


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)
           }
       })    
   });

解决方案

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.

这篇关于Chrome扩展与数据库API接口的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆