2011-06-28 14 views
29

के साथ फ़ाइल अपलोड करें मैं रेल ऐप में बैकबोन.जेएस का उपयोग कर रहा हूं और मुझे बैकबोन मॉडल में से किसी एक के हिस्से के रूप में फ़ाइल अपलोड करने की आवश्यकता है।बैकबोन

मुझे विश्वास नहीं है कि बैकबोन बॉक्स से बहु-भाग फ़ाइल अपलोड करने की अनुमति देता है। क्या किसी ने इसे कुछ प्लगइन या किसी अन्य बाहरी lib के माध्यम से काम करने में कामयाब रहा है? इसका समर्थन करने के लिए मैं Backbone.js कैसे बढ़ा सकता हूं?

उत्तर

20

विभिन्न तरीकों का उपयोग करके परीक्षण के कुछ महीनों के बाद अपने स्वयं के प्रश्न का उत्तर दें। मेरा समाधान निम्नलिखित है (रेल के साथ)।

फ़ाइल अपलोड की आवश्यकता वाले किसी भी रूप के लिए मैं data-remote="true" और enctype="multipart/form-data" सेट करता हूं और rails.js और jquery.iframe-transport.js शामिल करता हूं।

data-remote="true"rails.js के साथ सेट करने से मुझे ajax:success से जुड़ने और सफलता पर Backbone.js मॉडल बनाने की अनुमति मिलती है।

HTML:

<form action="/posts.js" method="post" data-remote="true" enctype="multipart/form-data"> 
    <input type="text" name="post[message]" /> 
    <input type="file" name="post[file]" /> 
    <button>Submit</button> 
</form> 

जावास्क्रिप्ट:

आप स्पष्ट रूप से ajax:error त्रुटि मामलों को संभालने के लिए बाध्य करना चाहिए।

मेरे लिए, डेटा ActiveRecord मॉडल में स्वच्छ है, इसलिए eval कथन के बारे में बहुत ज्यादा चिंता की जरूरत नहीं है।

$('form').bind('ajax:success', function(event, data) { 
    new Model(eval(data)); // Your newly created Backbone.js model 
}); 

रेल नियंत्रक:

class PostsController < ApplicationController 
    respond_to :js 

    def create 
    @post = Post.create(params[:post]) 
    respond_with @post 
    end 
end 

रेल देखें (create.js।हैमल):

remotipart मणि का उपयोग करना।

यह फॉर्म उस स्थिति को संभालेगा जब फॉर्म enctype सेट होने पर फ़ाइल अपलोड करता है, और जब ऐसा नहीं होता है।

आप यहां अपनी प्रतिक्रिया पर sanitize पर कॉल करना चुन सकते हैं।

= remotipart_response do 
    - if remotipart_submitted? 
    = "eval(#{Yajl::Encoder.encode(@post)});" 
    - else 
    =raw "eval(#{Yajl::Encoder.encode(@post)});" 
+0

साफ। हालांकि दो सवाल। आपके नियंत्रक में, क्या आप 'पोस्ट.न्यू (पैराम्स [: पोस्ट]) करने का इरादा रखते थे या आपने वास्तव में' पोस्ट.क्रेट (पैराम्स [: पोस्ट]) 'का मतलब लिया था? और दूसरा, आप '$ (' फॉर्म ') कहां रखेंगे। बाइंड (' AJAX: सफलता ')' कॉलबैक, बैकबोन में। दिए गए फॉर्म के लिए क्लास क्लास? धन्यवाद! –

+0

ग्रेट कैच, मेरे हिस्से पर टाइपो। यह 'post.create' होना चाहिए। मैं $ ('फॉर्म') रखूंगा। मेरे बैकबोन व्यू में बाइंड ('AJAX: सफलता') जो फॉर्म प्रस्तुत करता है। –

+0

फॉर्म में डेटा-प्रकार = "जेसन" जोड़ें और आप दृश्य को हटा सकते हैं। – maletor

0

मुझे लगता है कि आप गलत समझ रहे हैं कि रीढ़ की हड्डी कैसे काम करती है। बैकबोन जावास्क्रिप्ट के लिए एक एमवीसी लाइब्रेरी है, वेब सर्वर नहीं। फ़ाइल अपलोड क्लाइंट ब्राउज़र और आपके सर्वर के बीच बातचीत की जाती है। बैकबोन केवल मध्यम परत है जो आपको डेटा को व्यवस्थित और सुविधाजनक तरीके से व्यवस्थित करने में सहायता करती है।

कहा जा रहा है कि, आपको अपने मॉडल के साथ फ़ाइल को जोड़ने के लिए क्या करना है 1) रेल के साथ अपलोड को संभालें और फिर 2) अपने मॉडल के भीतर एक स्ट्रिंग में फ़ाइल का नाम और स्थान स्टोर करें।

http://khamsouk.souvanlasy.com/articles/ajax-file-uploads-in-rails-using-attachment_fu-and-responds_to_parent

एक बार जब आप list_item वस्तु वापस पाने, तो आप सिर्फ एक नए क्षेत्र अपने मॉडल में बना सकते हैं और list_item.filename और asset_path(list_item) स्टोर होगा:

तो यहाँ फ़ाइल अपलोड हिस्सा है।

उम्मीद है कि मदद करता है।

+0

इसके अलावा, यहां Django के लिए एक समान तो सवाल के लिए एक लिंक है http://stackoverflow.com/questions/6092596/backbone-js-link-file मॉडल के लिए – Swift

3

आप jquery.iframe.transport प्लगइन को देखना चाह सकते हैं। यदि आप रेल 3 का उपयोग कर रहे हैं, तो आप इसके बजाय remotipart का उपयोग कर सकते हैं (यह iframe.transport प्लगइन को बंडल करता है), जो रेल के यूजेएस ड्राइवर में स्वचालित रूप से AJAX अनुरोधों में फ़ाइल अपलोड के लिए समर्थन जोड़ने के लिए हुक करता है।

+0

धन्यवाद मैट। मैंने कुछ समय पहले जो वर्णन किया था उसका उपयोग करके समाप्त हो गया लेकिन इस सवाल को अपडेट करने के लिए चारों ओर नहीं मिला। –

0

आप पश्चगामी संगतता को तोड़ने के लिए कोई आपत्ति नहीं है, तो आप XHR2 and FormData

का लाभ ले सकते ऐसा नहीं है कि के रूप में सरल है:

var data = new FormData($('form.someForm').get(0)); 
$.ajax('http://*****.com', { 
    type:'POST', 
    data: data, 
    processData: false, 
    contentType: false // it automaticly sets multipart/form-data; boundary=... 
}); 
1

इस एक का पुनर्निर्माण करना।

पिछले जवाब में उल्लेख किया है, एक बहुखण्डीय/फार्म डेटा अनुरोध jQuery.ajax के माध्यम से क्रियान्वित किया जा सकता:

var formData = new FormData(); 
var input = document.getElementById('file'); 

formData.append('file', input.files[0]); 

$.ajax({ 
    url: 'path/to/upload/endpoint' 
    type:'POST', 
    data: formData, 
    processData: false, 
    contentType: false 
}); 

यह ध्यान देना भी महत्वपूर्ण है कि, बाहर के बॉक्स, Backbone.sync किसी भी मर्ज हो जाएगा model.save(null, { /* options here */ }) के माध्यम से $.ajax निर्देशों के साथ विकल्प।

आपका प्रक्रिया को बचाने के कुछ ऐसा दिखाई देगा:

var model = new Model({ 
    key: 'value' 
}); 
var input = document.getElementById('file'); 
var formData = new FormData(); 

_.each(model.keys(), function (key) { // Append your attributes 
    formData.append(key, model.get(key)); 
}); 

formData.append('file', input.files[0]); // Append your file 

model.save(null, { 
    data: formData, 
    processData: false, 
    contentType: false 
}); 
संबंधित मुद्दे