2016-06-22 157 views
0

我正在開發一個應用程序,它廣泛使用IndexedDB。我想要做的是保存員工的數據表和公司表的數據。

每個員工都屬於一個公司,而員工對象我有Company's ID,這兩個實體的對象都是這樣的。在回調中拋出IDBTransaction拋出TransactionInactiveError

公司的目標:

{"id":1,"name":"ABC"} 

員工對象:

{"id":100,"name":"E1","company_id":1} 

我節省使用自動遞增的關鍵公司的詳細信息(稱之爲appid),所以我的最終目標公司的外觀如下:

{"id":1,"name":"ABC","appid":1} 

當我插入公司的記錄時,appid會自動遞增。
現在同時將員工的目標,我想找到該公司的本地ID(appid)並將其保存在員工的目標,使員工的物體看起來像:

{"id":100,"name":"E1","company_id":1,"company_app_id":1} 

我能夠得到的本地ID公司通過調用一個方法,同時節省了員工的詳細信息,如:

var transaction = db.transaction(['employees'], 'readwrite'); 
var objStore = transaction.objectStore('employees'); 
var company_id=employeeobject.company_id; 
companyDB.getCompanyById(company_id,function(companyObject){ 
     transaction = db.transaction(['employees'], 'readwrite'); 
     objStore = transaction.objectStore('employees'); 
     // If I comment above two lines it throws me exception. 
     var request=objStore.put(employeeobject); 
     request.onsuccess = function (e) { 
      // using it for next insertion. 
     }; 
}); 

問題與上面的代碼是每次當我想插入員工在表中的數據,我需要重新在回調函數中trascation,因爲如果我不不開放交易再次拋出TransactionInactiveError

我在SO上搜索了特定的錯誤,發現事務一旦在當前範圍內不再使用就立即失效。

當我有幾個員工的對象時,上面的代碼工作得很好。 但是當我試圖用〜1K的數據執行相同的代碼時,它需要 (正常執行時間x〜10)。

正常執行時間我的意思是沒有獲取公司的localid並直接保存員工的詳細信息。


所以我的問題是,什麼是我可以插入員工的數據,包括公司的本地ID與至少執行時間的最佳方式?或者我做錯了什麼?

回答

0

嗯,也許這樣的事情有幫助嗎?

function addCompany(db, company, callback) { 
    var tx = db.transaction('companies', 'readwrite'); 
    var store = tx.objectStore('companies'); 
    var request = store.add(company); 
    request.onsuccess = callback; 
} 

function addEmployee(db, employee, callback) { 
    var tx = db.transaction('employees', 'readwrite'); 
    var store = tx.objectStore('employees'); 
    var request = store.add(employee); 
    request.onsuccess = callback; 
} 


function addCompanyThenEmployee(db, company, employee, callback) { 
    addCompany(db, company, onAddCompany); 

    function onAddCompany(event) { 
    var newAppId = event.target.result; 
    employee.company_app_id = newAppId; 
    addEmployee(db, employee, callback); 
    } 
} 


var company = {'id': 1, 'name': 'xyz'}; 
var employee = {'id': 1, 'name': 'xyz'}; 

var request = indexedDB.open(...); 
request.onsuccess = function(event) { 
    var db = event.target.result; 
    addCompanyThenEmployee(db, company, employee, onAddCompanyThenEmployee.bind(null, company, employee)); 
}; 

function onAddCompanyThenEmployee(company, employee, event) { 
    console.log('Added company', company, 'and employee', employee); 
}; 
+0

這將解決單一企業與單一的僱員。正如我在我的問題中提到的那樣,我寫的代碼對於單個條目可以很好地工作。我有更多的1K的公司和10K的員工。所以在這種情況下,我無法弄清楚這將如何工作! –

1

這取決於你如何實施companyDB.getCompanyById()。如您所見,索引DB數據庫事務僅在創建後立即生效(1),並且(2)在來自請求的回調中該事務,直到「控制返回到事件循環」。沒有進一步的細節,最好的辦法就是批量處理 - 爲N名員工執行getCompanyById()查找,然後編寫這N個記錄。

但是從頂部的描述「......員工表和公司表中的數據......」也許這是所有在一個單一的索引DB數據庫,在這種情況下,只使用一個單一的交易的一切:

var tx = db.transaction(['companies', 'employees'], 'readwrite'); 
employee_records.forEach(function(record) { 
    var company_id = record.company_id; 
    var req = tx.objectStore('companies').get(company_id); 
    req.onsuccess = function() { 
    var company = req.result; 
    record.company_app_id = company.app_id; 
    tx.objectStore('employees').put(record); 
    }; 
}); 

(我在這裏破壞您的實際數據/邏輯,這只是爲了說明)

+0

不,它與indexeddB數據庫不同。我首先插入數據庫中的所有公司,然後希望將公司的localid插入員工的詳細信息。在上述代碼/邏輯中根本沒有網絡呼叫。 –