2014-11-14 68 views
3

編輯14年11月16日:版本信息從createRecord(略灰燼數據屬於關聯異步關係)保存()序列

DEBUG: Ember  : 1.7.0 ember-1.7.0.js:14463 
DEBUG: Ember Data : 1.0.0-beta.10+canary.30d6bf849b ember-1.7.0.js:14463 
DEBUG: Handlebars : 1.1.2 ember-1.7.0.js:14463 
DEBUG: jQuery  : 1.10.2 

,我打我的頭撞牆試圖做一些事情,我認爲應該是相當直接與燼和燼數據,但我迄今沒有任何運氣。

本質上,我想使用服務器數據填充<select>下拉菜單。提交表格時,應根據用戶選擇的數據創建模型。然後將模型保存與餘燼數據並轉發到服務器具有以下格式:

{ 
    "File": { 
     "fileName":"the_name.txt", 
     "filePath":"/the/path", 
     "typeId": 13, 
     "versionId": 2 
    } 
} 

的問題是,在TYPEID和VERSIONID被排除在型號關係被定義爲異步像這樣:

App.File = DS.Model.extend({ 
    type: DS.belongsTo('type', {async: true}), 
    version: DS.belongsTo('version', {async: true}), 
    fileName: DS.attr('string'), 
    filePath: DS.attr('string') 
}); 

是困惑我,而且很可能在那裏我的錯誤所在的部分,是控制器:

App.FilesNewController = Ember.ObjectController.extend({ 
    needs: ['files'], 
    uploadError: false, 

    // These properties will be given by the binding in the view to the 
    //<select> inputs. 
    selectedType: null, 
    selectedVersion: null, 

    files: Ember.computed.alias('controllers.files'), 

    actions: { 
     createFile: function() { 
      this.createFileHelper(); 
     } 
    }, 

    createFileHelper: function() { 
     var selectedType = this.get('selectedType'); 
     var selectedVersion = this.get('selectedVersion'); 

     var file = this.store.createRecord('file', { 
       fileName: 'the_name.txt', 
       filePath: '/the/path' 
     }); 

     var gotDependencies = function(values) { 

      ////////////////////////////////////// 
      // This only works when async: false 
      file.set('type', values[0]) 
       .set('version', values[1]); 
      ////////////////////////////////////// 

      var onSuccess = function() { 
       this.transitionToRoute('files'); 
      }.bind(this); 

      var onFail = function() { 
       this.set('uploadError', true); 
      }.bind(this); 

      file.save().then(onSuccess, onFail); 
     }.bind(this); 

     Ember.RSVP.all([ 
      selectedType, 
      selectedVersion 
     ]).then(gotDependencies); 
    } 
}); 

當異步設置爲false,灰燼處理createRecord().save() POST請求正確。

當async爲true時,ember在多個請求下完全處理GET請求,但在createRecord().save()期間不會將belongsTo關係添加到文件JSON。只有基本屬性進行序列化:

{"File":{"fileName":"the_name.txt","filePath":"/the/path"}} 

我意識到這個問題已經被問過,但我還沒有找到一個滿意的答案迄今爲止,我還沒有發現任何適合我的需要。那麼,如何讓belongsTo關係正確地序列化呢?

只是爲了確保一切都在這裏,我將添加自定義序列我到目前爲止:

App.ApplicationSerializer = DS.RESTSerializer.extend({ 
    serializeIntoHash: function(data, type, record, options) { 
     var root = Ember.String.capitalize(type.typeKey); 
     data[root] = this.serialize(record, options); 
    }, 
    keyForRelationship: function(key, type){ 
     if (type === 'belongsTo') { 
      key += "Id"; 
     } 
     if (type === 'hasMany') { 
      key += "Ids"; 
     } 
     return key; 
    } 
}); 

App.FileSerializer = App.ApplicationSerializer.extend(DS.EmbeddedRecordsMixin, { 
    attrs: { 
     type: { serialize: 'id' }, 
     version: { serialize: 'id' } 
    } 
}); 

與選擇:

{{ view Ember.Select 
    contentBinding="controller.files.versions" 
    optionValuePath="content" 
    optionLabelPath="content.versionStr" 
    valueBinding="controller.selectedVersion" 
    id="selectVersion" 
    classNames="form-control" 
    prompt="-- Select Version --"}} 

如果有必要,我會另追加路由和控制器(FilesRoute,FilesController,VersionsRoute,TypesRoute)

編輯 11/16/14

我有一個工作解決方案(黑客?),我發現基於信息在兩個相關主題:

1)How should async belongsTo relationships be serialized?

2)Does async belongsTo support related model assignment?

從本質上講,所有我必須做的是移動Ember.RSVP.all()對性能get()後:

createFileHelper: function() { 
    var selectedType = this.get('selectedType'); 
    var selectedVersion = this.get('selectedVersion'); 

    var file = this.store.createRecord('file', { 
      fileName: 'the_name.txt', 
      filePath: '/the/path', 
      type: null, 
      version: null 
    }); 


    file.set('type', values[0]) 
     .set('version', values[1]); 

    Ember.RSVP.all([ 
     file.get('type'), 
     file.get('version') 
    ]).then(function(values) { 

     var onSuccess = function() { 
      this.transitionToRoute('files'); 
     }.bind(this); 

     var onFail = function() { 
      alert("failure"); 
      this.set('uploadError', true); 
     }.bind(this); 

     file.save().then(onSuccess, onFail); 
    }.bind(this)); 
} 

所以我需要get()保存模型之前屬於關係的屬性。我不知道這是否是一個錯誤。也許有更多關於emberjs的知識的人可以幫助解釋一下。

+0

我只是碰到了同樣的問題。任何更新? – 2014-12-28 07:35:17

+0

@torazaburo您是否在獲得承諾之前'.get()'屬性?即'set()'它們,然後在'.get()'上使用'.all()'或'.then()'。看到我的答案。 – nckturner 2014-12-31 00:57:17

+0

是的,我正在做'set',然後'get(...)。然後(...)'它正在工作,但這似乎已經嚴重破壞,我想知道你是否能找出更「優雅」的東西,至於Ember的任何東西都是優雅的。其實我沒有做一個單獨的'set',而是將散列值傳遞給'createRecord'。 – 2014-12-31 03:04:44

回答

1

詳情參見問題,但我保存時用屬於關聯關係的模型(和你特別需要這種關係被序列化)爲我工作的通用的答案是調用.get()的屬性,然後save()他們在then()

它歸結爲:

var file = this.store.createRecord('file', { 
     fileName: 'the_name.txt', 
     filePath: '/the/path', 
     type: null, 
     version: null 
}); 

// belongsTo set() here 
file.set('type', selectedType) 
    .set('version', selectedVersion); 

Ember.RSVP.all([ 
    file.get('type'), 
    file.get('version') 
]).then(function(values) { 

    var onSuccess = function() { 
     this.transitionToRoute('files'); 
    }.bind(this); 

    var onFail = function() { 
     alert("failure"); 
     this.set('uploadError', true); 
    }.bind(this); 

    // Save inside then() after I call get() on promises 
    file.save().then(onSuccess, onFail); 

}.bind(this));