javascript - Backbone.Marionette.ItemView के लिए div wrap को बंद करना





backbone.js (5)


यह समाधान पुनः प्रतिपादन के लिए काम करता है। आपको render ओवरराइड render आवश्यकता है।

onRender ट्रिक्स फिर से प्रस्तुत करने के लिए काम नहीं करेंगे। वे हर पुनः प्रस्तुत करने पर घोंसले का कारण बनेंगे।

BM.ItemView::render = ->
  @isClosed = false
  @triggerMethod "before:render", this
  @triggerMethod "item:before:render", this
  data = @serializeData()
  data = @mixinTemplateHelpers(data)
  template = @getTemplate()
  html = Marionette.Renderer.render(template, data)

  #@$el.html html
  $newEl = $ html
  @$el.replaceWith $newEl
  @setElement $newEl

  @bindUIElements()
  @triggerMethod "render", this
  @triggerMethod "item:rendered", this
  this

मैं यहां एंग्री बिल्लियों बैकबोन / मैरियनेट ट्यूटोरियल पोस्ट देख रहा हूं

http://davidsulc.com/blog/2012/04/15/a-simple-backbone-marionette-tutorial/

http://davidsulc.com/blog/2012/04/22/a-simple-backbone-marionette-tutorial-part-2/

और मैं यहां पोस्ट किए गए एक ही प्रश्न / आवश्यकता पर आया:

बैकबोन.जेएस रेंडर में div द्वारा लपेटना बंद कर देता है

लेकिन मैं केवल बैकबोन के लिए काम करने के लिए इसे प्राप्त कर सकता हूं। दृश्य, बैकबोन नहीं। Marionette.ItemViews।

उदाहरण के लिए, उपरोक्त सरल रीढ़ की हड्डी मेरियनेट ट्यूटोरियल लिंक से, AngryCatView लें:

AngryCatView = Backbone.Marionette.ItemView.extend({
  template: "#angry_cat-template",
  tagName: 'tr',
  className: 'angry_cat',
  ...
});

टेम्पलेट, #angry_cat-template , इस तरह दिखता है:

<script type="text/template" id="angry_cat-template">
  <td><%= rank %></td>
  <td><%= votes %></td>
  <td><%= name %></td>
  ...
</script>

मुझे क्या पसंद नहीं है, यह है कि AngryCatView की आवश्यकता है

  tagName: 'tr',
  className: 'angry_cat',

- अगर मैं टैग नाम लेता tagName , तो angry_cat-template को <div> द्वारा लपेटा जाता है।

मैं क्या चाहता हूं कि एचटीएमएल को एक ही स्थान (गुस्से में _at-टेम्पलेट) में निर्दिष्ट करना है और न ही cross.tat- टेम्पलेट में सबसे HTML (सभी <td> टैग) और AngryCatView में एक छोटा HTML ( <tr> टैग) नहीं है। मैं इसे angry_cat-template में लिखना चाहता हूं:

<script type="text/template" id="angry_cat-template">
  <tr class="angry_cat">
    <td><%= rank %></td>
    <td><%= votes %></td>
    <td><%= name %></td>
    ...
  </tr>
</script>

यह सिर्फ मेरे लिए क्लीनर महसूस करता है लेकिन मैं डेरिक बेली के जवाब के साथ मिल रहा हूं "बैकबोन.जेएस रेंडर में div द्वारा लपेटना बंद कर देता है" और इसे बैकबोन के लिए काम नहीं कर सकता। मैरियनेट।

कोई विचार?




यह पूरा करने के लिए jQuery के बजाय वेनिला जेएस का उपयोग करने के लिए क्लीनर नहीं होगा?

var Layout = Backbone.Marionette.LayoutView.extend({

  ...

  onRender: function () {
    this.setElement(this.el.innerHTML);
  }

  ...

});



IE9 + के लिए आप केवल पहले firstElementChild और childElementCount उपयोग कर सकते हैं:

var Layout = Backbone.Marionette.LayoutView.extend({

  ...

  onRender: function () {
      if (this.el.childElementCount == 1) {
          this.setElement(this.el.firstElementChild);
      }
  }

  ...

});

एक अच्छा कारण है कि मैरियनेट स्वचालित रूप से रैपर डीआईवी डालने का कारण बनता है। यह तभी होता है जब आपके टेम्पलेट में केवल एक तत्व होता है जब आप इसे छोड़ सकते हैं। इसलिए बाल तत्वों की संख्या के लिए परीक्षण।

एक और विकल्प प्रत्येक Marionette दृश्य में attachElContent विधि का उपयोग करना है। इसका डिफ़ॉल्ट कार्यान्वयन का अर्थ है दृश्य के पुन: प्रस्तुतकर्ता मूल तत्व के आंतरिक HTML को ओवरराइट करेंगे। यह अंततः बेजोनबी के जवाब में उल्लिखित अनंत घोंसले को जन्म देता है।

यदि आप रेन्डर पर ओवरराइट नहीं करेंगे और / या शुद्ध-जेएस समाधान की आवश्यकता है, तो निम्न कोड केवल वही हो सकता है जो आप चाहते हैं:

var Layout = Backbone.Marionette.LayoutView.extend({

  ...

  attachElContent: function (html) {
      var parentEl = this.el.parentElement;
      var oldEl;

      //View already attached to the DOM => re-render case => prevents
      //recursive nesting by considering template's top element as the
      //view's when re-rendering
      if (parentEl) {
          oldEl = this.el;
          this.setElement(html);                   //gets new element from parsed html
          parentEl.replaceChild(this.el, oldEl);   //updates the dom with the new element 
          return this;

      //View hasn't been attached to the DOM yet => first render 
      // => gets rid of wrapper DIV if only one child
      } else {
          Marionette.ItemView.prototype.attachElContent.call(this, html);
          if (this.el.childElementCount == 1) {
              this.setElement(this.el.firstElementChild);
          }
          return this;
      }
  }

  ...

});

ध्यान दें कि काम करने के लिए पुन: प्रस्तुत करने के लिए, कोड एक टेम्पलेट को एक बच्चे के साथ मानता है जिसमें सभी मार्कअप होते हैं।




2014/02/18 - टिप्पणियों में @ वॉन और @ थॉम-निकोलस द्वारा उल्लिखित सुधारों को समायोजित करने के लिए अपडेट किया गया

मेरे कई आइटम व्यू / लेआउट में मैं यह करता हूं:

var Layout = Backbone.Marionette.Layout.extend({

    ...

    onRender: function () {
        // Get rid of that pesky wrapping-div.
        // Assumes 1 child element present in template.
        this.$el = this.$el.children();
        // Unwrap the element to prevent infinitely 
        // nesting elements during re-render.
        this.$el.unwrap();
        this.setElement(this.$el);
    }

    ...

});

उपर्युक्त कोड केवल तब काम करता है जब रैपर div में एक तत्व होता है, इस प्रकार मैं अपने टेम्पलेट्स को डिज़ाइन करता हूं।

आपके मामले में .children() <tr class="angry_cat"> वापस आ जाएगा, इसलिए यह सही काम करना चाहिए।

मैं सहमत हूं, यह टेम्पलेट्स को अधिक क्लीनर रखता है।

ध्यान देने योग्य एक बात:

यह तकनीक केवल 1 बाल तत्व को मजबूर नहीं करती है। यह अंधाधुंध पकड़ता है .children() ताकि अगर आपने एक से अधिक तत्वों को वापस करने के लिए टेम्पलेट का गलत तरीके से निर्माण किया है, जैसे 3 <td> तत्वों के साथ पहले टेम्पलेट उदाहरण की तरह, यह अच्छी तरह से काम नहीं करेगा।

यह आपके टेम्पलेट को एक तत्व को वापस करने की आवश्यकता है, क्योंकि आपके पास रूट <tr> तत्व के साथ दूसरे टेम्पलेट में है।

बेशक इसे आवश्यकता के लिए परीक्षण करने के लिए लिखा जा सकता है।

जिज्ञासा के लिए यहां एक कामकाजी उदाहरण है: http://codepen.io/somethingkindawierd/pen/txnpE




document.createElement('div');




javascript backbone.js marionette