2013-02-07 39 views
12

क्या बैकबोन.जेएस और इसका मॉडल आर्किटेक्चर का उपयोग करने का कोई तरीका है कि मैं सर्वर पर फॉर्मडाटा ऑब्जेक्ट भेज सकता हूं? जिस समस्या में मैं चल रहा हूं वह यह है कि बैकबोन भेजता है सब कुछ जेएसओएन के रूप में एन्कोड किया गया है, इसलिए फॉर्मडाटा ऑब्जेक्ट ठीक से नहीं भेजा गया है (जाहिर है)।बैकबोन.जेएस और फॉर्मडाटा

मैं अस्थायी रूप से सीधे jQuery AJAX अनुरोध करके और फॉर्मडाटा ऑब्जेक्ट को डेटा प्रॉपर्टी के रूप में उपयोग करके इस पर काम कर रहा हूं, लेकिन यह आदर्श से कम है।

+0

आप ओवरराइड कर सकते हैं [ 'sync'] (http://backbonejs.org/#Sync) विश्व स्तर पर, प्रति-मॉडल, या प्रति-संग्रह सर्वर से किसी भी तरह से आप चाहते हैं बात करने के लिए। –

+0

अरे, आपका सुझाव वह दृष्टिकोण था जिसके साथ मैं गया था। इसे उत्तर के रूप में सबमिट करने के लिए स्वतंत्र महसूस करें और मैं इसे स्वीकार करूंगा। – Leonidas

उत्तर

7

बस, यहाँ कैसे मैं इसके बारे में चला गया sync ओवरराइड करने के लिए बिना इस प्रश्न का उत्तर जोड़ने के लिए:

$('#' + $(e.currentTarget).data('fileTarget')).trigger('click').unbind('change').bind('change', function(){ 
    var form_data = new FormData(); 
    form_data.append('file', $(this)[0].files[0]); 
    appManager.trigger('user:picture:change', form_data); 
}); 

जो फिर एक से चलाता है: मेरी नजर में

, मैं somethign की तरह है एक नियंत्रक कि यह करता है में समारोह:

var picture_entity = new appManager.Entities.ProfilePicture(); 
picture_entity.save(null, { 
    data: data, 
    contentType: false, 
    processData: false, 
}); 

उस समय, मैं jQuery के data अधिभावी कर रहा हूँ मेरी FormData साथ वस्तु।

7

मैं एक ऐसी ही आवश्यकता थी और यहाँ मैं क्या किया है:

देखें में:

var HomeView = Backbone.View.extend({ 
    el: "#template_loader", 
    initialize: function() { 
     console.log('Home View Initialized'); 
    }, 
    render: function() { 
     var inputData = { 
      cId: cId, 
      latitude: latitude, 
      longitude: longitude 
     }; 

     var data = new FormData(); 

     data.append('data', JSON.stringify(inputData)); 

     that.model.save(data, { 
      data: data, 
      processData: false, 
      cache: false, 
      contentType: false, 
      success: function (model, result) { 
       alert("Success"); 
      }, 
      error: function() { 
       alert("Error"); 
      } 
     }); 
    } 
});  

आशा इस मदद करता है।

16

sync विधि को ओवरराइड करके एक समाधान है, जिसका उपयोग मैं फ़ाइल अपलोड की अनुमति देने के लिए करता हूं।

इस मामले में मैं मॉडल की sync विधि को ओवरराइड करता हूं, लेकिन यह Backbone.sync विधि भी हो सकता है।

var FileModel = Backbone.Model.extend({ 

    urlRoot: CMS_ADMIN_URL + '/config/files', 

    sync: function(method, model, options){ 

    // Post data as FormData object on create to allow file upload 
    if(method == 'create'){ 
     var formData = new FormData(); 

     // Loop over model attributes and append to formData 
     _.each(model.attributes, function(value, key){ 
     formData.append(key, value); 
     }); 

     // Set processData and contentType to false so data is sent as FormData 
     _.defaults(options || (options = {}), { 
     data: formData, 
     processData: false, 
     contentType: false 
     }); 
    } 
    return Backbone.sync.call(this, method, model, options); 
    } 
}); 

संपादित करें:

अपलोड प्रगति पर नज़र रखने के लिए, आप एक xhr विकल्प के विकल्प के लिए जोड़ सकते हैं:

... 

_.defaults(options || (options = {}), { 
    data: formData, 
    processData: false, 
    contentType: false 
    xhr: function(){ 
    // get the native XmlHttpRequest object 
    var xhr = $.ajaxSettings.xhr(); 
    // set the onprogress event handler 
    xhr.upload.onprogress = function(event) { 
     if (event.lengthComputable) { 
     console.log('%d%', (event.loaded/event.total) * 100); 
     // Trigger progress event on model for view updates 
     model.trigger('progress', (event.loaded/event.total) * 100); 
     } 
    }; 
    // set the onload event handler 
    xhr.upload.onload = function(){ 
     console.log('complete'); 
     model.trigger('progress', 100); 
    }; 
    // return the customized object 
    return xhr; 
    } 
}); 

... 
+2

यह एक अच्छा जवाब है, आईएमओ इस पृष्ठ पर सबसे अच्छा है। सर्वर संचार को संभालने का उचित तरीका यहां मॉडल स्तर पर सिंक विधि को संपादित करना है, लेकिन यह * बंद * को व्यापक रूप से बंदर-पैच करने की आवश्यकता नहीं है: बस संपादित करें विकल्प हैश (डेटा और एक्सएचआर विकल्प धारण करना), और आप कर चुके हैं। – chikamichi

2

मैं एक ही मुद्दा था। आप इसे हल करने के तरीके से ऊपर देख सकते हैं।

var $form = $("myFormSelector"); 

//==> GET MODEL FROM FORM 
var model = new MyBackboneModel(); 
var myData = null; 
var ajaxOptions = {}; 
// Check if it is a multipart request. 
if ($form.hasFile()) { 
    myData = new FormData($form[0]); 
    ajaxOptions = { 
     type: "POST", 
     data: myData, 
     processData: false, 
     cache: false, 
     contentType: false 
    }; 
} else { 
    myData = $form.serializeObject(); 
} 

// Save the model. 
model.save(myData, $.extend({}, ajaxOptions, { 
    success: function(model, data, response) { 
     //==> INSERT SUCCESS 
    }, 
    error: function(model, response) { 
     //==> INSERT ERROR 
    } 
})); 

हैफ़ाइल एक कस्टम विधि है जो JQuery फ़ंक्शंस को बढ़ाती है।

$.fn.hasFile = function() { 
    if ($.type(this) === "undefined") 
     return false; 

    var hasFile = false; 
    $.each($(this).find(":file"), function(key, input) { 
     if ($(input).val().length > 0) { 
      hasFile = true; 
     } 
    }); 

    return hasFile; 
}; 
2

बस Backbone.emulateJSON = true; का उपयोग करें: http://backbonejs.org/#Sync-emulateJSON

कारण होगा JSON एक मॉडल पैरामीटर के तहत धारावाहिक जा करने के लिए है, और अनुरोध आवेदन/x-www फार्म-urlencoded MIME प्रकार के साथ किए जाने के लिए, जैसे कि एक HTML फॉर्म से।

+0

लेकिन यह JSON को स्ट्रिंग करने के लिए क्रमबद्ध करता है, और ऑब्जेक्ट की तरह स्ट्रिंग के रूप में प्रदर्शित होता है। –

+0

यह फॉर्मडेटा ऑब्जेक्ट बनाता है और इसे सर्वर पर भेजता है –

1

मेरे लिए कोई भी जवाब काम नहीं करता है, नीचे सरल और आसान समाधान है। sync विधि और options.contentType इस तरह अधिभावी द्वारा:

sync: function(method, model, options) { 
    options = _.extend({ 
     contentType : 'application/x-www-form-urlencoded;charset=UTF-8' 
    }, options); 

    options.data = jQuery.param(model.toJSON()); 

    return Backbone.sync.call(this, method, model, options); 
} 
0

एक साधारण से एक होगी, उम्मीद है कि इस में किसी को मदद मिलेगी।

  1. रीढ़ मॉडल की एक वस्तु बनाएँ:

    var importModel = new ImportModel(); 
    
  2. कॉल सहेजें [पोस्ट] बैकबोन मॉडल की विधि और FormData वस्तु दर्रा।

    var objFormData = new FormData(); 
    objFormData.append('userfile', files[0]); 
    
    importModel.save(objFormData, { 
    contentType: false, 
    data: objFormData, 
    processData: false, 
    success: function(data, status, xhr) { }, 
    error: function(xhr, statusStr) { } 
    }); 
    

 संबंधित मुद्दे

  • कोई संबंधित समस्या नहीं^_^