2011-12-13 8 views
5

का उपयोग backbone.js ...सरणी को अपडेट करते समय मॉडल की परिवर्तन घटना आग नहीं होगी?

@model.bind 'change',()-> console.log 'updated' 

addIndex = (index) => 
    array = @model.get('array') 
    array.push index 
    @model.set 
     array: array 

यह पूरी तरह से मॉडल को अद्यतन करता है, लेकिन परिवर्तन घटना को गति प्रदान नहीं करता है। क्या किसी को पता है कि मैंने जो पोस्ट किया है उसे देखते हुए?

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

मैं इस जोड़ा गया है और यह परिवर्तन घटना से चलाता है:

@model.set 
    test: '' 

num = 0 
setInterval()=> 
    num++ 
    @model.set 
    test: num 
, 3000 

मैं इस जोड़ा गया है और यह परिवर्तन घटना ट्रिगर नहीं करता:

@model.set 
    test: [] 

num = 0 
setInterval()=> 
    console.log 'testupdate' 
    num++ 
    test = @model.get('test') 
    test.push num 
    @model.set 
     test: test 
, 3000 
+0

आबादी आ रही है? – Brian

+0

हाँ मॉडल अद्यतन ठीक है, और सरणी मॉडल विशेषताओं में सही ढंग से आबादी है। – fancy

उत्तर

6

समस्या है कि आप मौजूदा मान के साथ मूल्य निर्धारित कर रहे हैं। स्रोत कोड पर एक नज़र डालें:

http://documentcloud.github.com/backbone/docs/backbone.html#section-33

जब आप set यह सुनिश्चित करें कि आप एक ही मूल्य की स्थापना नहीं कर रहे हैं कि सुनिश्चित करने के लिए एक गार्ड खंड है फोन (घटना छोरों से बचने के लिए)। आपके मामले में, आप सरणी प्राप्त कर रहे हैं, इसे संशोधित कर रहे हैं, और इसे फिर से सेट कर रहे हैं, जो आपके ईवेंट को ट्रिगर नहीं करेगा।

बेशक

, जब आप set test: {}, यह एक नई वस्तु के साथ एक नया आइटम है, इसलिए इसे फिर से ट्रिगर किया जाएगा। क्या तुम सच में घटना ट्रिगर करना चाहते हैं, तो आप फिर से आबादी वाले सरणी के लिए अशक्त करने के लिए सेट कर सकते हैं, तो एक खाली सरणी के लिए सेट और फिर ...

8

कारण के रूप में ब्रायन के जवाब अद्भुत है!

एक और तरीका क्या आप इसे बाहर nulling या सरणी क्लोनिंग के बजाय चाहते हैं पेश करने के लिए चाहता था।

बस मैन्युअल रूप से परिवर्तन को गति प्रदान अपने आप को:

addIndex = (index) => 
    array = @model.get('array') 
    array.push index 
    @model.trigger('change:array',@model, array) 
+0

यदि आपके पास विशेष रूप से बड़ी सरणी क्लोनिंग है तो यह एक खराब विकल्प है।यह रास्ता और अधिक समझ में आता है। –

+0

इस समाधान के साथ model.changed अपडेट नहीं किया जाएगा। – postnerd

1

आप के बजाय एक रीढ़ संग्रह का उपयोग करके एक सरणी की, और फिर उस संग्रह में होने वाली घटनाओं को बदलने के लिए बाध्य करने पर विचार कर सकता है?

7

आप संदर्भित वस्तु स्थापित कर रहे हैं के बाद से, _.clone() का उपयोग करें।

test = _.clone @model.get('test') 
test.push num 
@model.set test: test 

जब से तुम नहीं रह ही स्थापित करने के लिए संदर्भित वस्तु/पंक्ति का उपयोग करते हैं, तो यह परिवर्तन घटना अगर यह बदल गया है सक्रिय हो जाएगा।

6

दूसरा तरीका इस प्रकार, जब वस्तुओं या सरणियों को बदलने, नए अद्यतन मूल्य निर्धारित करने से पहले चुपचाप सेट किए बिना संपत्ति है। कुछ इस तरह:

(function() { 
    var arr, model = new Model(); 

    model.set("arrayProp", [1, 2, 3]); 
    arr = model.get("arrayProp"); 
    arr.push(4); 

    model.unset("arrayProp", { silent: true }); 
    model.set("arrayProp", arr); 
})(); 

silent: true सेट करते समय प्रोप unsetting करके, परिवर्तन घटना केवल एक बार (set() विधि कहा जाता है और संपत्ति अद्यतन किया गया है जब) सक्रिय हो जाएगा।

वहाँ वास्तव में इस या कर मैन्युअल रूप से घटना बुला के बीच एक अंतर नहीं है, यह व्यक्तिगत पसंद का मामला है।

+2

मैं इस विकल्प को पसंद करता हूं - इस तरह बैकबोन डिफ़ॉल्ट पैरामीटर के साथ सभी ईवेंट वेरिएंट ('चेंज' और 'चेंज: एरेप्रॉप') को निकाल देता है, इसलिए यह किसी भी श्रोताओं को तोड़ नहीं देगा। – joews

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