2012-07-02 19 views
37

में एक गणना किए गए अवलोकन योग्य सरणी को कैसे बनाएं I want to know computed अवलोकन योग्य सरणी कैसे बनाएं।नॉकआउट

मेरे दृश्य मॉडल में, मेरे पास 2 अवलोकन योग्य सरणी हैं, और मैं एक गणना करने योग्य अवलोकन योग्य सरणी रखना चाहता हूं जो केवल दोनों सरणी संयुक्त है।

function ViewModel() { 
    var self = this; 
    self.listA= ko.observableArray([]); 
    self.listB = ko.observableArray([]); 
    self.masterList= //combine both list A and B 

उत्तर

33

यह दो सरणी को जोड़ देगा और संयुक्त सूची वापस करेगा। हालांकि, यह एक गणना योग्य अवलोकन योग्य सरणी नहीं है (यह नहीं पता कि यह भी संभव है), लेकिन नियमित रूप से गणना की जाने योग्य।

self.masterList = ko.computed(function() { 
    return this.listA().concat(this.listB()); 
}, this); 
+18

मेरा मानना ​​है कि यह उत्तर अधिकांश उपयोग-मामलों के लिए त्रुटिपूर्ण है: गणना किए गए अवलोकन योग्य का मूल्य एक नियमित सरणी है, एक अवलोकन योग्य सरणी नहीं (लगभग जवाब में कहा गया है)। इसलिए, 'listA' या' listB' को अपडेट करना पूरी तरह से अपनी सामग्री को अपडेट करने के बजाय सरणी को प्रतिस्थापित करेगा (जो हम 99% मामलों में चाहते हैं)। ** इसका मतलब है कि आपको इस अवलोकन करने के लिए विचारों को बाध्य नहीं करना चाहिए। ** असल में, यह कोड इसके गैर-गणना वाले संस्करण के रूप में उपयोगी है। विभिन्न दृष्टिकोणों के लिए अन्य उत्तरों देखें। – tne

+0

यह इस मामले में काम नहीं करेगा, लेकिन नॉकआउट प्लगइन [नॉकआउट-अनुमान] (https://github.com/stevesanderson/knockout-projections) नए [सरणी परिवर्तन सदस्यता] का उपयोग करके कहीं अधिक कुशल गणना वाले अवलोकन योग्य सरणी लागू करता है (http://blog.stevensanderson.com/2013/10/08/knockout-3-0-release-candidate-available/)। इस प्लगइन को एक कुशल कॉन्सट ऑपरेशन का समर्थन करने के लिए बढ़ाया जा सकता है। – Singularity

7

एक observableArray कुछ और गुणों के साथ सिर्फ एक मानने योग्य है। इसलिए, एक गणना किए गए अवलोकन योग्य जो बंद करने में एक सरणी देता है उसे एक सरणी के रूप में माना जाएगा।

+3

ठीक है, तरह। मैंने अभी इसका परीक्षण किया है और ऐसा लगता है कि जब तक इसे एक अवलोकन योग्य सरणी के रूप में घोषित नहीं किया जाता है, तो शिफ्ट और पॉप जैसी विधियां आपके लिए नहीं टूटी जाती हैं। – Eirinn

9

मैं जानता हूँ कि यह एक पुराने सवाल है, लेकिन मैंने सोचा कि मैं वहाँ में मेरा उत्तर फेंक चाहते हैं:

var u = ko.utils.unwrapObservable; 

ko.observableArray.fn.filter = function (predicate) { 
    var target = this; 

    var computed = ko.computed(function() { 
     return ko.utils.arrayFilter(target(), predicate); 
    }); 

    var observableArray = new ko.observableArray(u(computed)); 

    computed.subscribe(function (newValue) { observableArray(newValue); }); 

    return observableArray; 
}; 
10
self.masterList = ko.observableArray(); 
ko.computed(function() { 
    self.masterList(self.listA().concat(self.listB())); 
}); 

भावना में जो Flateau के जवाब की तरह, लेकिन मुझे लगता है कि इस विधि सरल है पसंद ।

+0

इस तरह मैं इसे भी करने जा रहा था, लेकिन क्या यह अभी भी स्वीकार्य उत्तर के रूप में इस मुद्दे से पीड़ित नहीं है; उसमें किसी भी बदलाव से 'मास्टरलिस्ट' को पूरी तरह से फिर से खींचा जा सकता है? –

+0

@AdamLewis: हां, यह वास्तव में पूरे सरणी का पुनर्निर्माण करता है, और व्यू इंजन के आधार पर यह पूरे डोम सबग्राफ को फिर से प्रस्तुत नहीं कर सकता है, जो भी विचारों के लिए बाध्य है (आवश्यक नहीं है, केवल एक अंतर और लागू हो सकता है यह)। ध्यान दें कि कई अपडेट से बचने के लिए यह अभी भी सबसे अच्छा समाधान हो सकता है। यह आपके द्वारा उल्लिखित उत्तर के बारे में उल्लिखित मुद्दा नहीं है, जहां दृश्य इंजन स्वयं सरणी संपत्ति को कैप्चर करता है (जैसा कि इसके पथ के विपरीत है) तो यह कभी पता नहीं लगाएगा कि आपने सरणी को बदल दिया है (क्योंकि यह देखने योग्य नहीं है) और इस प्रकार * बिल्कुल * अपडेट नहीं होगा। – tne

+0

@tne मैं अभी इस जवाब का उपयोग कर रहा हूं, लेकिन यह वास्तव में धीमा लगता है ... शायद मैं कुछ और गलत कर रहा हूं। हालांकि, क्या यह समाधान केओ के उद्देश्य के उद्देश्य को तोड़ रहा है?एक गणना योग्य अवलोकन सरणी की आवश्यकता की समस्या को हल करने का एक और तरीका है? बस सोच रहा है कि यह मेरे (या किसी भी) स्थिति में उपयोग करने का सही उपकरण है या नहीं। – Nate

2

मुझे यकीन नहीं है कि यह सबसे कुशल विकल्प है - लेकिन यह काफी सरल है और मेरे लिए काम करता है। ko.computed रिटर्न के रूप में नीचे एक नमूदार सरणी:

self.computedArrayValue = ko.computed(function() { 
    var all = ko.observableArray([]); 
    .... 
    return all(); 
}); 

कोड भाषा का काम उदाहरण: एचटीएमएल:

<div data-bind="foreach: days"> 
    <button class="btn btn-default btn-lg day" data-bind="text: $data, click: $root.dayPressed"></button>   
</div> 
दृश्य मॉडल पर

जावास्क्रिप्ट समारोह:

self.days = ko.computed(function() { 
    var all = ko.observableArray([]); 
    var month = self.selectedMonth(); //observable 
    var year = self.selectedYear();  //observable 
    for (var i = 1; i < 29; i++) { 
     all.push(i); 
    } 
    if (month == "Feb" && year % 4 == 0) { 
     all.push(29); 
    } else if (["Jan","Mar","May","Jul","Aug","Oct","Dec"].find((p) => p == month)) { 
     [29,30,31].forEach((i) => all.push(i)); 
    } else if (month != "Feb") { 
     [29,30].forEach((i) => all.push(i));     
    } 
    return all(); 
});