2017-02-10 13 views
1

私はSQLite pluginでオフラインで動作させるためにCordova /角型アプリケーションを構築しようとしていますが、これは私の状況であるデータベースへの約束と非同期の問題です:角度の入れ子になったループの約束

私はこのように構成された5台持っている:idとpage_idのでIDとタグ 表PageMenusとID、タイトル、TEMPLATE_IDと身体 表のメニューで

表ページとページとメニュー 表を関連付けることmenu_id menu_idのidを持つMeniItemsと、教師のメニューの "実際の"要素を持つbody idがaのテーブルテンプレートndタグを使用して適切な表示を選択する

互換性の理由から(私はwebappとモバイルアプリケーションに同じコードを使用していますが、モバイルでは私のAPIを呼び出すwebappではデバイスのすべてのコンテンツをダウンロードしています)私はすでに適切なフォーマットを取得することができるよ

{ 
    "id": 1 
    "body": "Welcome to the homepage", 
    "title": "Homepage", 
    "template_tag": "tab", 
    "menus": [ 
    { 
     "id": 3, 
     "tag": "home_menu", 
     "menu_items": [ 
     { 
      "menu_id": 3, 
      "body": "Movie" 
     }, 
     { 
      "menu_id": 3, 
      "body": "Restaurant" 
     }, 
     { 
      "menu_id": 3, 
      "body": "Messages" 
     }, 
     { 
      "menu_id": 3, 
      "body": "Systems" 
     } 
     ] 
    }, 
    { 
     "id": 62, 
     "tag": "user_menu", 
     "menu_items": [ 
     { 
      "menu_id": 62, 
      "body": "About" 
     }, 
     { 
      "menu_id": 62, 
      "body": "Updates" 
     }, 
     { 
      "menu_id": 62, 
      "body": "Help" 
     }, 
     { 
      "menu_id": 62, 
      "body": "Reset Password" 
     }, 
     { 
      "menu_id": 62, 
      "body": "Report/ Feedback" 
     } 
     ] 
    } 
    ] 
} 

が、私の問題は、コントローラが前にメニューの体にアクセスしようとしていることであるがこのように解決され、私はエラーがこれを未定義取得:この形式でページをretriveする必要があります私はthemomentで私の工場で使用しているコードです:

return { 
    getHomePage: function() { 
    // other function 
    }, 
    getPage: function(id) { 
    var results = $q.defer(); 

    function request() { 
     var res = {}; 
     var queryPage = "SELECT pages.id, pages.body, pages.title, templates.tag AS template_tag FROM pages JOIN templates ON pages.template_id = templates.id WHERE pages.id = ?"; 
     $cordovaSQLite.execute(db, queryPage, [id]).then(function(page) { 
     res = page.rows.item(0); 
     res.menus = []; 
     var queryMenus = "SELECT menus.id, menus.tag FROM menus JOIN page_menus ON menus.id = page_menus.menu_id WHERE page_menus.page_id = ?"; 
     $cordovaSQLite.execute(db, queryMenus, [res.id]).then(function(menus) { 
      for (var i = 0; i < menus.rows.length; i++) { 
      var menu = { 
       id: menus.rows.item(i).id, 
       tag: menus.rows.item(i).tag, 
       menu_items: [] 
      }; 
      var queryMenuItems = "SELECT * FROM menu_items JOIN menus ON menu_items.menu_id = menus.id where menus.id = ?" 
      $cordovaSQLite.execute(db, queryMenuItems, [menus.rows.item(i).id]).then(function(menu_items) { 
       for (var i = 0; i < menu_items.rows.length; i++) { 
       menu.menu_items.push(menu_items.rows.item(i)); 
       } 
      }); 
      res.menus.push(menu); 
      }; 
      results.resolve(res); 
     }); 
     }); 
    }; 
    request(); 

    return results.promise; 
    }, 
    getMedia: function(id) { 
    // other function 
    } 
}; 
+0

あなたが 'ui-router'を使っているなら' resolve'を見てください。問題は、データが利用できないときにデータを要求することです。 'resolve'アプローチは、状態がロードされる前にデータをロードして、期待どおりのものを確保できるようにします。そのコードを見るだけであなたのコンテキストを定義するのは難しいです。 –

答えて

0

これは、(私は頻繁に私のDBの構造に基づいているので、他の誰かのために、本当に参考になるとは思わない場合でも、それを投稿)私がやって終わるものです:

var promisePage = $cordovaSQLite.execute(db, "SELECT p.*, t.tag AS template_tag FROM pages AS p JOIN templates AS t ON p.template_id = t.id WHERE p.id = ?", [id]); 
var promiseMenus = $cordovaSQLite.execute(db, "SELECT m.* FROM menus AS m JOIN page_menus AS pm ON m.id = pm.menu_id WHERE pm.page_id = ?", [id]); 
var promiseMenuItems = $cordovaSQLite.execute(db, "SELECT mi.* FROM menu_items AS mi JOIN menus AS m ON mi.menu_id = m.id JOIN page_menus AS pm ON pm.menu_id = m.id WHERE pm.page_id = ?", [id]); 

return $q.all([promisePage, promiseMenus, promiseMenuItems]).then(function(data) { 
    var page = data[0].rows.item(0); 
    var menus = data[1]; 
    var menuItems = data[2]; 
    // here there is some boring code to construct the page 
    return page; 

私はページを手に入れた後にデータベースをクエリするのではなく、3つの要素すべてを並列にクエリし、すべての作業を$ q.allで行います。

0

これは、チェーンへの良い練習が道を約束します:

getSomething: function(...) { 
    return requestReturningPromise1.then(function(resultOfPromise1) { 
     // Do something here (prepare next request,...) 
     return requestReturningPromise2; 
    }).then(function(resultOfPromise2) { 
     // Do something here (prepare next request,...) 
     return requestReturningPromise3;  
    }).then(function(resultOfPromise3) { 
     // Do something here (prepare next request,...) 
     return finalReturn;  
    }); 
} 

ネスティングが低減され、それがより読みやすく、デバッグが簡単です。

MyService.getPage(id).then(function(page) { 
    // here, bind the result page to your controller scope ... 
}); 
:あなたはあなたのコントローラでこのようにそれを消費する必要がありますので、上記のコードでは、サービス自体は約束を返すこと

getPage: function(id) { 
    var res = {}; 
    var queryPage = "SELECT pages.id, pages.body, pages.title, templates.tag AS template_tag FROM pages JOIN templates ON pages.template_id = templates.id WHERE pages.id = ?"; 
    return $cordovaSQLite.execute(db, queryPage, [id]).then(function(page) { 
     res = page.rows.item(0); 
     res.menus = []; 
     var queryMenus = "SELECT menus.id, menus.tag FROM menus JOIN page_menus ON menus.id = page_menus.menu_id WHERE page_menus.page_id = ?"; 
     return $cordovaSQLite.execute(db, queryMenus, [res.id]); 
    }).then(function(menus) { 
     var menuPromises = []; 
     for (var i = 0; i < menus.rows.length; i++) { 
      var menu = { 
       id: menus.rows.item(i).id, 
       tag: menus.rows.item(i).tag, 
       menu_items: [] 
      }; 
      var queryMenuItems = "SELECT * FROM menu_items JOIN menus ON menu_items.menu_id = menus.id where menus.id = ?"; 
      var menuPromise = $cordovaSQLite.execute(db, queryMenuItems, [menus.rows.item(i).id]).then(function(menu_items) { 
       for (var i = 0; i < menu_items.rows.length; i++) { 
        menu.menu_items.push(menu_items.rows.item(i)); 
       } 
       return menu; 
      });  
      menuPromises.push(menuPromise);       
     } 
     return Promise.all(menuPromises);   
    }).then(function(menus) { 
     for (var i = 0; i < menus.length; i++) { 
      res.menus.push(menus[i]); 
     } 
     return res; 
    }); 
} 

注: だからあなたのコードにそれを適用すると、このような何かを与えます

関連する問題