Расширение Chrome с интерфейсом API базы данных - PullRequest
0 голосов
/ 28 июня 2011

Я хочу обновить div со списком якорей, которые я генерирую из локальной базы данных в chrome.Это довольно простая вещь, но как только я пытаюсь добавить данные в файл 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)
           }
       })    
   });

1 Ответ

0 голосов
/ 30 июня 2011

Изучив приведенный выше код, я заметил, что вы выполняете функцию "self._load ()" в конце каждой функции вашего API.База данных HTML5 SQL является асинхронной, вы никогда не сможете гарантировать результат.В этом случае я бы предположил, что результат всегда будет 0 или случайным, потому что это будет условие гонки.

Я сделал нечто подобное в своем расширении fb-exporter, не стесняйтесь посмотреть, как я это сделалhttps://github.com/mohamedmansour/fb-exporter/blob/master/js/database.js

Чтобы решить подобную проблему, вы проверили веб-инспектора и посмотрите, нет ли каких-либо ошибок на фоновой странице.Я полагаю, это все на фоне страницы, а?Попытайтесь выяснить, не произошла ли какая-либо ошибка, если нет, я считаю, что вы столкнулись с расой.Просто переместите загрузку в обратный вызов, и он должен правильно вызвать загрузку.

Что касается вашего первого вопроса с атрибутом unlimited storage manifest, он вам не нужен для этого случая, это не должно быть проблемой,Ограничение веб-баз данных составляет 5 МБ (последнее, насколько я помню, оно могло измениться), если вы используете много манипуляций с данными, то вы используете этот атрибут.

Просто убедитесь, что вы можете гарантировать, что this.database.allработает после инициализации базы данных.

...