2014-04-21 31 views
1

我有這些模型:灰燼,保存記錄用的hasMany關係創建界面右邊的方式

Gmcontrolpanel.Offer = DS.Model.extend({ 
    name: DS.attr('string'), 
    date: DS.attr('string'), 
    duration: DS.attr('number'), 

    products: DS.hasMany('product', {async: true}), 
}); 

Gmcontrolpanel.Product = DS.Model.extend({ 
    name: DS.attr('string'), 
    description: DS.attr('string'), 

    offer: DS.belongsTo('offer'), 
    variations: DS.hasMany('variation', {async: true}) 
}); 

Gmcontrolpanel.Variation = DS.Model.extend({ 
    description: DS.attr('string'), 
    quantity: DS.attr('number'), 
    price: DS.attr('string'), 

    product: DS.belongsTo('product') 
}); 

我試圖建立一個可重複使用的界面,用於創建/編輯的要約;我爲插入產品和插入變體提出了兩個單獨的視圖;

該產品視圖有一個+和一個 - 按鈕來添加或刪除產品,以及相同的變異視圖;

路由的型號是:

model: function() { 
    return this.get('store').createRecord('offer'); 
} 

我想的是,在點擊保存按鈕時,所有(報價,產品和變種)被保存;

首先:哪一個是最好的實現方式? containerViews? collectionViews或{{#each}}循環?

然後,如何創建子記錄並將它們綁定到子視圖上的輸入字段?我的意思是:每次插入productView時,我都可以創建新的產品記錄,並且變體的內容相同,但在保存時如何獲取所有這些記錄並正確設置所有關係字段?

回答

1

下面是如何建立的關係的骨架例如:

var newOffer= store.createRecord('offer', {name:....}); 
//or you can do newOffer.set('name',...); 

var newVariation = store.createRecord('variation', {description:.....}); 

var newProduct = store.createRecord('product', {name:..., description:.....}); 

newProduct.get('variations').pushObject(newVariation); 

newOffer.get('products').pushObject(newProduct); 

但保存模型和數據庫堅持它,有一個小問題。保存是按照每個模型進行的,因此,即使您在保存商品模型時正確設置了關係,它也不會嵌入與hasMany關係模型關聯的數據。所以我們可以這樣做:

注意:我已經閱讀了關於批量保存的內容,但還沒有嘗試過 - 你可能想要嘗試一下,但如果沒有效果,那麼我會保存每個模型自下而上像

newVariation.save().then(function(){ 
    newProduct.get('variations').pushObject(newVariation); 
    //since the variation model is already saved, it has id associated with the model 
    //so ember data now knows that it should set variations as variations:[id of the variation model we just saved] when sending post request for product 
    newProduct.save().then{ //same pattern as above } 
}, function(){//handle failure} 

這裏的情況很簡單,我們只有一個變體和一個產品,但你可能有多個。我們可以做rsvp.all同步保存的承諾,但它有點呆滯,因爲你必須爲每次保存進行單獨的API調用,並且因爲你可能有多種變體和產品,所以沒有ajax調用可能有點瘋狂。解決這個問題的一種方法是通過循環遍歷模型來創建自己的json結構,並將這些模型組合成單個json,並使用jQuery ajax api調用發出單個post請求,將內容保存到數據庫中,然後使用pushPayload( http://emberjs.com/api/data/classes/DS.Store.html#method_pushPayload)將所有數據加載回商店。

這就是我在類似情況下所做的,但可能有更多優雅的解決方案,所以我會等待更多的意見。

至於視圖的事情,我想你需要的只是產品的圖,這就是即時通訊思想:

利用ProductView相關
//offer.hbs 
Bunch of form elemnts to update name description 
+ - buttons to add product 
{{#each product}} 
    {{#view productView product=this}}//this is just a normal view 
{{/each}} 

//你的模板會像

+ - buttons to add variations to product 
{{#each product.variations}} 
    Show form elments to update name and description 
{{/each}} 
+0

好的,謝謝你的這個;它在幫助;這個觀點如何:你認爲在這種情況下最好的是什麼?我的意思是,因爲需要在主視圖中顯示許多產品視圖,並且在任何產品視圖中顯示許多變體視圖,所以最佳選擇是什麼?將它們推入containerViews(一個在主視圖中,一個在每個productsView中);或者將它們推入collectionViews(容器和collectionview之間的區別是什麼?)或其他東西... –

+0

我已經更新了關於我認爲會視圖的用法的答案。我沒有使用過collectionView,但是使用了containerView,而collectionView似乎可以擴展容器視圖,但是在你的情況下,普通視圖應該足夠了。 –

+0

謝謝你的幫助,我已經接受你的答案,因爲它正在把我推向正確的方向;特別是將兒童記錄推入父母關係的方式是我在文檔中找不到的一步... –

0

還有另一個我不明白的問題;我使用相同的觀點來創建和編輯報價;什麼樣的變化僅僅是模式:創建當我使用:

model: function() { 
    return this.get('store').createRecord('offer'); 
} 
編輯(使用另一條路線相同的模板)我有當

​​

它的工作原理只是偶爾:爲創建路線一切正常,但對於編輯路線,它只在瀏覽器刷新後才起作用;如果不是(如果來自另一條路線),我收到一個錯誤,說我試圖查找產品,但記錄沒有加載; 問題是我可以看到提供的網絡請求已發送,並且接收到所有需要的側裝數據的答案;我也試着補充:

setupController: function() { 
    model.refresh(); 
} 

但沒有什麼變化;在另一篇文章中,我發現我應該用async標記關係:true; 與此它工作,但事情是使用異步,當來自另一條路線時,Ember數據發送許多http請求爲產品,但產品記錄已經存在,sideloaded在模型中(被強迫由model.refresh重新加載());

爲什麼Ember無法等待model.refresh並從響應中取出記錄而不是詢問產品記錄?

+0

這聽起來像你不能正確加載嵌套的數據,看看這篇文章是關於如何我們可以加載嵌套數據http://stackoverflow.com/questions/19244014/ember-data-nested-models/19345990#19345990。當我不想要異步加載時,我已經寫下了json結構應該如何。此外,您可能不想在setupController上執行刷新,因爲setupController已獲取控制器和模型http://emberjs.com/guides/routing/setting-up-a-controller/。 –

+0

是的,服務器已經以正確的方式發送嵌套數據;問題是隻有當你來自/提供路線(即提供名稱列表)時,它纔會執行模型掛鉤;在該路由嵌套記錄不加載(這是有意避免加載產品帶寬浪費,這裏不需要)...然後,過渡到/ offer /:id以查看要約的細節,它需要加載嵌套的記錄;如果它會在這裏執行模型鉤子,則問題將得到解決,因爲單個商品的模型會正確加載嵌套記錄... –

+0

如何轉換爲offer /:id路由。無論是使用link-to還是transitionTo,在這兩種情況下,您都需要傳遞模型,因此模型掛鉤會在您的路由中轉義。它只有當你想直接去提供/:id路由(通過url直接)你會打到模型鉤 –

0

怎麼樣,如果我們給這setupController

setupController:function(controller, model){ 
    model.reload().then(function(data){controller.set('model', data);}); 
} 

或者,如果你所創造的一個動作過渡到編輯模式,並在行動,你先和內重新加載模型一試其再勾,你使用重新加載的模型數據執行transitionToRoute。例如:

goToEdit: function(model){ 
    model.reload().then(function(data){transitionToRoute('offer.edit', data}); 
} 
+0

這會在加載路由時給出錯誤;可能是因爲,與執行模型鉤子時發生的不同,setupController鉤子不會停止執行下面的代碼,或者執行得太晚......在任何情況下,我都可以看到視圖中的代碼在模型重新加載之前執行當嘗試訪問模型時,它會導致錯誤 –