नॉकआउट व्यू मॉडल्स के बीच का अंतर, ऑब्जेक्ट वर्सेल्स बनाम फ़ंक्शंस के रूप में घोषित किया गया है


195

नॉकआउट js में मैं देख रहा हूँ मॉडल देखें या तो घोषित:

var viewModel = {
    firstname: ko.observable("Bob")
};

ko.applyBindings(viewModel );

या:

var viewModel = function() {
    this.firstname= ko.observable("Bob");
};

ko.applyBindings(new viewModel ());

दोनों में क्या अंतर है, यदि कोई है तो?

मुझे यह चर्चा नॉकआउट Google समूह पर मिली, लेकिन इसने मुझे वास्तव में संतोषजनक उत्तर नहीं दिया।

मैं एक कारण देख सकता हूं यदि मैं मॉडल को कुछ डेटा के साथ आरंभीकृत करना चाहता था, उदाहरण के लिए:

var viewModel = function(person) {
    this.firstname= ko.observable(person.firstname);
};

var person = ... ;
ko.applyBindings(new viewModel(person));

लेकिन अगर मैं ऐसा नहीं कर रहा हूं तो इससे कोई फर्क नहीं पड़ता कि मैं किस शैली को चुनता हूं?


मुझे विश्वास नहीं होता कि कोई अंतर है। मैं आमतौर पर कंस्ट्रक्टर पैटर्न का उपयोग करता हूं, क्योंकि मेरे पास अक्सर ऐसी विधियां होती हैं जिन्हें मैं घोषित करना चाहता हूं prototype(वे विधियां जो अक्सर, उदाहरण के लिए, सर्वर से डेटा प्राप्त करते हैं और तदनुसार दृश्य मॉडल को अपडेट करते हैं)। हालाँकि आप अभी भी स्पष्ट रूप से उन्हें एक वस्तु शाब्दिक संपत्ति के रूप में घोषित कर सकते हैं, इसलिए मैं वास्तव में अंतर नहीं देख सकता।
जेम्स एलार्डिस

4
इसका नॉकआउट से कोई लेना-देना नहीं है, और जावास्क्रिप्ट में कस्टम ऑब्जेक्ट्स की तात्कालिकता में आसानी के साथ सब कुछ करना है
zzzzBov

1
@Kev अगर viewModel एक कंस्ट्रक्टर फ़ंक्शन है, तो आप इसे वैयक्तिकोडमॉडल = फ़ंक्शन () {...} की तरह ही अपरकेस में लिखें;
एलिज़ाबेथ

जवाबों:


252

अपने दृश्य मॉडल को परिभाषित करने के लिए फ़ंक्शन का उपयोग करने के कुछ फायदे हैं।

मुख्य लाभ यह है कि आपके पास thisउस मूल्य के लिए तत्काल पहुंच है जो बनाए जा रहे उदाहरण के बराबर है। इसका मतलब है कि आप कर सकते हैं:

var ViewModel = function(first, last) {
  this.first = ko.observable(first);
  this.last = ko.observable(last);
  this.full = ko.computed(function() {
     return this.first() + " " + this.last();
  }, this);
};

तो, आपकी गणना की गई वेधशाला उपयुक्त मान के लिए बाध्य हो सकती है this, भले ही उसे अलग-अलग दायरे से कहा जाए।

एक वस्तु शाब्दिक के साथ, आपको करना होगा:

var viewModel = {
   first: ko.observable("Bob"),
   last: ko.observable("Smith"),
};

viewModel.full = ko.computed(function() {
   return this.first() + " " + this.last();
}, viewModel);

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

एक और पैटर्न जिसे आप यह सुनिश्चित करने के लिए उपयोग कर सकते हैं कि thisहमेशा उचित मूल्य के बराबर फ़ंक्शन में एक चर सेट करना है thisऔर इसके बजाय इसका उपयोग करना है। यह इस तरह होगा:

var ViewModel = function() {
    var self = this;
    this.items = ko.observableArray();
    this.removeItem = function(item) {
         self.items.remove(item);
    }
};

अब, अगर आप अलग आइटम और कॉल के दायरे में हैं $root.removeItem, का मूल्य thisइच्छा वास्तव में होना डेटा उस स्तर (जो आइटम होगा) पर बाध्य किया जा रहा। इस मामले में स्वयं का उपयोग करके, आप यह सुनिश्चित कर सकते हैं कि इसे समग्र दृश्य मॉडल से हटाया जा रहा है।

एक अन्य विकल्प का उपयोग कर रहा है bind, जो आधुनिक ब्राउज़रों द्वारा समर्थित है और यदि यह समर्थित नहीं है, तो KO द्वारा जोड़ा जाता है। उस मामले में, ऐसा लगेगा:

var ViewModel = function() {
    this.items = ko.observableArray();
    this.removeItem = function(item) {
         this.items.remove(item);
    }.bind(this);
};

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


1
बहुत बढ़िया जवाब। मैं अक्सर दृश्यमॉडल जैसी जटिल वस्तुओं के लिए एक फ़ंक्शन (खुलासा मॉड्यूल पैटर्न का उपयोग करके) का उपयोग करता हूं। लेकिन सरल मॉडल के लिए, मैं एक फ़ंक्शन का उपयोग करता हूं ताकि मैं एक जगह पर सब कुछ संभाल सकूं।
जॉन पापा

1
@ जॉनपाप - बस अपने प्लुरसाइट वीडियो को नॉकआउट पर देख रहे थे (सिर्फ आधे रास्ते से - और संयोग से, बस ऑब्जेक्ट शाब्दिक बनाम फ़ंक्शन पर अनुभाग देखा गया था)। वास्तव में अच्छी तरह से किया है और पैसा छोड़ने में मदद की है। अकेले उस के लिए एक महीने की सदस्यता के लायक है।
केव

@ केव - धन्यवाद। खुशी है कि आप इसे से बाहर कर रहे हैं। कुछ भी नहीं है कि मॉड्यूल के बारे में परवाह नहीं वास्तव में एक नॉकआउट अवधारणा, जावास्क्रिप्ट पैटर्न के अधिक है। लेकिन मैंने पाया कि जैसा कि मैं नॉकआउट के साथ आगे बढ़ा कि उन अवधारणाओं ने मुझे वास्तव में क्लीनर को अधिक स्थिर कोड बनाने में मदद की। वैसे भी, खुशी है कि आप इसका आनंद लेते हैं :)
जॉन पापा

self.items = ko.observableArray () नहीं होना चाहिए; अपने दूसरे उदाहरण में? आपने इसका इस्तेमाल किया, क्या यह सही है?
जैकनोवा

1
निर्माण कार्य में @JackNova selfऔर thisसमान हैं, इसलिए या तो समतुल्य होंगे। निष्कासन कार्यक्रम में, selfयह अधिक उपयोगी हो जाता है, क्योंकि thisबच्चे के आइटम के संदर्भ में निष्पादित होने पर वर्तमान उदाहरण नहीं होगा।
आरपी नीमेयर

12

मैं एक अलग विधि का उपयोग करता हूं, हालांकि समान है:

var viewModel = (function () {
  var obj = {};
  obj.myVariable = ko.observable();
  obj.myComputed = ko.computed(function () { return "hello" + obj.myVariable() });

  ko.applyBindings(obj);
  return obj;
})();

कारणों की जोड़ी:

  1. उपयोग नहीं कर रहा है this, जो कि ko.computeds आदि के भीतर उपयोग करते समय भ्रम हो सकता है
  2. मेरा नजरिया एक एकल है, मुझे कई उदाहरण बनाने की जरूरत नहीं है (अर्थात new viewModel())

यह मॉड्यूल पैटर्न का खुलासा कर रहा है यदि गलत नहीं है। अच्छा जवाब लेकिन सवाल इस पैटर्न के बारे में नहीं था।
फिल

@ अंपुल: पुराने धागे के लिए पूछने के लिए क्षमा करें। यू ने कहा My viewModel is a singleton, I don't need to create multiple instances (i.e. new viewModel()) लेकिन यह स्पष्ट नहीं है कि आप क्या कहने की कोशिश कर I don't need to create multiple instances सकते हैं कि आप अधिक उपयोग कर सकते हैं ताकि कोई आपके दृष्टिकोण का फायदा समझ सके। धन्यवाद
मऊ

IMO, कारणों में से एक जिसे आप ViewModel घोषित करेंगे function, क्योंकि आप इसे एक से अधिक बार निष्पादित करेंगे। हालाँकि, इसके बारे में मेरे उदाहरण में, यह एक तुरंत लागू किया गया अनाम फ़ंक्शन है, इसलिए इसे एक से अधिक बार नहीं बनाया जाएगा। यह उपरोक्त उदाहरण में वस्तु शाब्दिक के समान है, लेकिन आपको अधिक अलगाव प्रदान करता है
pulslater19
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.