Backbone: मॉडल के अंदर संग्रह को मॉडल करने का सबसे अच्छा तरीका क्या है?

को निर्मित 4 नव॰ 2010  ·  11टिप्पणियाँ  ·  स्रोत: jashkenas/backbone

मेरी टीम, एक दिलचस्प डेटा स्कीमा के साथ काम कर रही है। मूल रूप से हमारे पास एक दस्तावेज है जिसमें एक नाम और संस्करण है और इससे संबंधित वस्तुओं की एक सरणी है। आइटम में स्वयं उनके साथ जुड़े आईडी नहीं होते हैं क्योंकि वे बड़े मॉडल से संबंधित होते हैं लेकिन आइटम को मुख्य दस्तावेज़ से जोड़ा/संपादित/हटाया जा सकता है। मॉडल कुछ इस तरह दिखता है:
{
नाम: "टेस्ट",
संस्करण 1,
आइटम: [
{नाम: "आइटम 1",
स्थिति: 0},
{नाम: "आइटम 2",
पद : 1}]
}

मॉडल में अंतर्निहित वस्तुओं के लिए संग्रह का उपयोग करना बहुत अच्छा होगा लेकिन जब भी संग्रह अपडेट हो जाता है, तो मॉडल को अपने यूआरएल के साथ सर्वर पर वापस पोस्ट करना चाहिए। बैकबोन में इसे मॉडल करने का सबसे अच्छा तरीका क्या है? अगर अधिक जानकारी की आवश्यकता है तो मुझे संक्षेप में और पोस्ट करने में खुशी होगी।

question

सबसे उपयोगी टिप्पणी

@eranation : नहीं, काफी समान होना चाहिए। इस पैटर्न का उपयोग करते समय, मैं items को अपने एट्रिब्यूट हैश से बाहर रखना पसंद करता हूं, इसलिए मुझे उन्हें सिंक में रखने की आवश्यकता नहीं है। इसके लिए आवश्यक है कि आप items ऑब्जेक्ट को पार्सिंग के लिए प्रतिक्रिया से बाहर निकालें, और इसे क्रमबद्ध करने के लिए वापस जोड़ें (नीचे देखें)। इसके अलावा, आप उस तर्क को रखना चाहेंगे जो @rsim ने initialize में अपनी constructor पद्धति में डाला है, और on बजाय bind (जो अर्ध-पदावनत है)।

मुझे लगता है कि जहां संभव हो, गुण केवल उथले हैश (कोई नेस्टेड संग्रह, मॉडल इत्यादि) नहीं होना बहुत आसान है।

var Document = Backbone.Model.extend({
  constructor: function() {
    this.items = new ItemSet(null, {document: this});
    this.items.on('change', this.save, this);
    Backbone.Model.apply(this, arguments);
  },
  parse: function(resp) {
    this.items.set(resp.items, {parse: true, remove: false});
    delete resp.items;
    return resp;
  },
  toJSON: function() {
    var attrs = _.clone(this.attributes);
    attrs.items = this.items.toJSON();
    return attrs;
  }
});
var ItemSet = Backbone.Collection.extend({
  model: Item,
  initialize: function(models, options) {
    this.document = options.document;
  }
});
var Item = Backbone.Model.extend({
  // access document with this.collection.document
});
var document1 = new Document({
  name: "Test",
  version: 1,
  items: [
    {name : "Item 1", position : 0},
    {name : "Item 2", position : 1}
  ]
});

ऐसा लगता है कि गहराई से नेस्टेड स्कीमा के लिए भी अच्छा काम करता है। ( दस्तावेज़ देखें)

सभी 11 टिप्पणियाँ

मैं कहूंगा कि आपके पास दो मुख्य विकल्प हैं... पहला यह है कि आइटम को वैनिला विशेषता के रूप में छोड़ दिया जाए। विशेषताएँ बदलने पर बैकबोन एक गहरी समानता जाँच का उपयोग करता है, इसलिए यदि कोई आंतरिक आइटम अपडेट किया जाता है, तो दस्तावेज़ को इसके बारे में पता चल जाएगा।

दूसरा विकल्प यह है कि दस्तावेज़ से आइटम को बाहर निकाला जाए और दस्तावेज़ पर अटके संग्रह के अंदर उन्हें अपने आप में मॉडल के रूप में संलग्न किया जाए (हम दस्तावेज़क्लाउड पर इन पंक्तियों के साथ कुछ करते हैं)। उदाहरण के लिए (मोटे तौर पर बोल):

var Document = Backbone.Model.extend({
  initialize: function() {
    this.items = new ItemSet();
    this.items.bind('change', this.save);
  }
});

क्या इनमें से कोई भी आपके लिए अच्छा काम करता है?

मैं "दस्तावेज़" संपत्ति को दस्तावेज़ ऑब्जेक्ट में वापस जोड़ने की भी सिफारिश करता हूं जिसे आइटम से आवश्यक होने पर एक्सेस किया जा सकता है:

var Document = Backbone.Model.extend({
  initialize: function() {
    this.items = new ItemSet(this.get('items'), {document: this});
    this.items.bind('change', this.save);
  }
});
var ItemSet = Backbone.Collection.extend({
  initialize: function(models, options) {
    this.document = options.document;
  }
});
var Item = Backbone.Model.extend({
  // access document with this.collection.document
});
var document1 = new Document({
  name: "Test",
  version: 1,
  items: [
    {name : "Item 1", position : 0},
    {name : "Item 2", position : 1}
  ]
});

मेरा मानना ​​​​है कि आइटम की परिवर्तन घटना को दस्तावेज़ सहेजने के लिए बाध्य करना गायब टुकड़ा है। हालाँकि, आइटमसेट में दस्तावेज़ को जोड़ना भी बहुत मददगार लगता है। हम आज इसे आजमाएंगे और मैं आप लोगों को बताऊंगा कि यह कैसे निकलता है।

यह अच्छी तरह से काम किया। अब हमारे पास सबसे बड़ा मुद्दा मोंगोइड के साथ है। मदद के लिए बहुत शुक्रिया दोस्तों।

मैं सभी वस्तुओं को एक साथ सहेजने के बारे में कैसे जाउंगा? जब भी कोई आइटम बदला जाता है, तो मैं हर बार अनुरोध नहीं करना चाहता, लेकिन मैं उन सभी को उपयोगकर्ता की कार्रवाई पर एक ही अनुरोध के साथ सहेजना चाहता हूं। मैं सब कुछ इकट्ठा करने के बारे में सोच रहा था जब दस्तावेज़ सहेजा गया था और दस्तावेज़ के 'आइटम' एटीआर को अपडेट कर रहा था। क्या यह एक अच्छा समाधान है?

जब तक आपके आइटम दस्तावेज़ में सेट हैं, तब जब आप कोई दस्तावेज़.सेव () करते हैं तो आइटम सर्वर पर भी भेजे जाएंगे।

लेकिन मान लें कि यदि मैं रनटाइम पर संग्रह document1.items में कोई आइटम जोड़ता हूं तो यह दस्तावेज़ 1 की 'आइटम' विशेषता में स्वचालित रूप से नहीं जुड़ता है। तो अगर मैं एक document1.save() करता हूं, तो संग्रह में जोड़ा गया नया मॉडल सर्वर पर नहीं भेजा जाएगा। मैं नहीं देख सकता कि संग्रह में परिवर्तन मॉडल की विशेषताओं में कैसे प्रचारित हो सकते हैं जो सहेजने के साथ भेजे जाते हैं।

तो, यहां बताया गया है कि हम इसे कैसे संभाल रहे हैं: दस्तावेज़ में एक डिफ़ॉल्ट आइटम सरणी है। आरंभीकरण पर, एक अतिभारित सेट विधि में, मैं विशेषताओं से एक नया आइटम संग्रह बनाता हूं और उसे दस्तावेज़ पर सेट करता हूं।

class Document extends Backbone.Model
  defaults:
    items: []

  set: (attrs, options) ->
    items = attrs['items']
    if _( items ).isArray()
      if _( items ).isEmpty()
        attrs['items'] = new DocumentItemsCollection
        newItem = new Item
        attrs['items'].add(newItem, { silent: true })
      else
        attrs['items'] = new DocumentItemsCollection items

उस समय आप केवल 'प्राप्त', 'सेट', 'जोड़ें' और 'निकालें' के साथ आइटम संग्रह विधियों से निपटते हैं। आप डॉट नोटेशन के साथ खिलवाड़ नहीं करते हैं। मेरे पास दस्तावेज़ पर परिवर्तन की घटनाओं को आग लगाने के लिए AddItem और deleteItem नामक मेरे दस्तावेज़ वर्ग पर भी विधियां हैं। जब आप दस्तावेज़ पर एक सेव () करते हैं तो यह आपके आइटम संग्रह पर JSON को कॉल करेगा।

ईमानदारी से, यह हमारे दस्तावेज़ों के लिए एक साधारण मामला है और हमारे पास और भी गहरे उप-दस्तावेज़ हैं। रीढ़ की हड्डी के साथ जटिलता की इस मात्रा से निपटना, और मॉडलों पर कई तरीकों को ओवरलोड करना, गधे में एक वास्तविक बड़ा दर्द है। अब हम भविष्य में बैकबोन को स्प्राउटकोर से बदलने पर विचार कर रहे हैं।

यदि आपको वास्तव में जटिल दस्तावेजों से निपटना है तो मैं सुझाव दूंगा कि आप ExtJS या स्प्राउटकोर देखें। बैकबोन साधारण मॉडल के साथ एक छोटी परियोजना के लिए बहुत अच्छा है, लेकिन जब वस्तुएं/बातचीत तेज होने लगती हैं तो बहुत जल्दी टूट जाती हैं।

क्या 1.0 के लिए इसके लिए कोई नया "सर्वोत्तम अभ्यास" है?

@eranation : नहीं, काफी समान होना चाहिए। इस पैटर्न का उपयोग करते समय, मैं items को अपने एट्रिब्यूट हैश से बाहर रखना पसंद करता हूं, इसलिए मुझे उन्हें सिंक में रखने की आवश्यकता नहीं है। इसके लिए आवश्यक है कि आप items ऑब्जेक्ट को पार्सिंग के लिए प्रतिक्रिया से बाहर निकालें, और इसे क्रमबद्ध करने के लिए वापस जोड़ें (नीचे देखें)। इसके अलावा, आप उस तर्क को रखना चाहेंगे जो @rsim ने initialize में अपनी constructor पद्धति में डाला है, और on बजाय bind (जो अर्ध-पदावनत है)।

मुझे लगता है कि जहां संभव हो, गुण केवल उथले हैश (कोई नेस्टेड संग्रह, मॉडल इत्यादि) नहीं होना बहुत आसान है।

var Document = Backbone.Model.extend({
  constructor: function() {
    this.items = new ItemSet(null, {document: this});
    this.items.on('change', this.save, this);
    Backbone.Model.apply(this, arguments);
  },
  parse: function(resp) {
    this.items.set(resp.items, {parse: true, remove: false});
    delete resp.items;
    return resp;
  },
  toJSON: function() {
    var attrs = _.clone(this.attributes);
    attrs.items = this.items.toJSON();
    return attrs;
  }
});
var ItemSet = Backbone.Collection.extend({
  model: Item,
  initialize: function(models, options) {
    this.document = options.document;
  }
});
var Item = Backbone.Model.extend({
  // access document with this.collection.document
});
var document1 = new Document({
  name: "Test",
  version: 1,
  items: [
    {name : "Item 1", position : 0},
    {name : "Item 2", position : 1}
  ]
});

ऐसा लगता है कि गहराई से नेस्टेड स्कीमा के लिए भी अच्छा काम करता है। ( दस्तावेज़ देखें)

@ akre54 धन्यवाद, यह एक अच्छा उदाहरण है, बहुत सराहना की

क्या यह पृष्ठ उपयोगी था?
0 / 5 - 0 रेटिंग्स