2012-04-13 15 views
25

के साथ संपत्ति परिवर्तनों की सदस्यता लेता है क्या वैसे भी मैं सभी संपत्ति परिवर्तनों की सदस्यता लेने के लिए नॉकआउट मैपिंग प्लगइन बता सकता हूं, एक निश्चित फ़ंक्शन को कॉल करें?नॉकआउटजेएस मैपिंग प्लगइन

मुझे पता है मैं मैन्युअल रूप से इस तरह से संपत्ति परिवर्तन घटना की सदस्यता ले सकते:

var viewModel = { 
    name: ko.observable('foo'), 
} 

// subscribe manually here 
viewModel.name.subscribe(function(newValue){ 
    // do work 
}) 

मैं सामान्य रूप से, हालांकि सदस्यता के लिए के बाद से मेरे विचार मॉडल भिन्न हो सकते हैं सक्षम होने के लिए चाहते हैं, मैं नहीं करना चाहता संपत्ति के नाम हार्डकोड। मैंने एक ऐसा फ़ंक्शन बनाया जो ऐसा करता है, लेकिन यह सबसे अच्छा तरीका नहीं हो सकता है। यह आईई 7 और नीचे छोड़कर सभी ब्राउज़रों पर काम करता है।

यहाँ मैं एक तर्क के रूप में एक viewmodel लेने के लिए और यह गुण की सदस्यता पर चिंतन करने का प्रयास करें:

function subscribeToKO(data) { 

     $.each(data, function (property, value) { 
      if (getType(value) == "Object") 
       data[property] = subscribeToKO(value); 
      else if (getType(value) == "Array") { 
       $.each(value, function (index, item) { 
        item = subscribeToKO(item); 
       }); 
      } 
      else { 
       if (value.subscribe) { 
        value.subscribe(function (newValue) { 
         // do work           
        }); 
       } 
      } 
     }); 
     return data; 
    } 

जैसे कि मैंने कहा था कि यह काम करता है, लेकिन जब से मैं मानचित्रण pluging उपयोग कर रहा हूँ मैं उम्मीद कर रहा था एक हुक मैं इसे एक ऐसे फ़ंक्शन के साथ उपयोग करने के लिए उपयोग कर सकता हूं जो सामान्य रूप से संपत्ति परिवर्तनों की सदस्यता लेगा।

mapping = { 
    create: function(options){ 
     options.data.subscribe(function(newValue){ 
      // do work ??? 
     }); 
    } 
} 

ko.mapping.fromJS(viewModel, mapping); 

कोई भी विचार:

तरह?

उत्तर

9

यहां Ryan Niemeyer's dirty flag पर आधारित एक सामान्य दृष्टिकोण है।
JsFiddle के लिए यहां क्लिक करें।

एचटीएमएल:

<ol> 
<li> 
    Telephone : <input data-bind="value: telephone"/> 
</li> 
<li> 
    Address : <input data-bind="value: address"/> 
</li> 
</ol>​ 

जावास्क्रिप्ट:

var model = { 
    telephone: ko.observable('0294658963'), 
    address: ko.observable('167 New Crest Rd') 

}; 
// knockout extension for creating a changed flag (similar to Ryan's dirty flag except it resets itself after every change) 
ko.changedFlag = function(root) { 
    var result = function() {}; 
    var initialState = ko.observable(ko.toJSON(root)); 

    result.isChanged = ko.dependentObservable(function() { 
     var changed = initialState() !== ko.toJSON(root); 
     if (changed) result.reset(); 
     return changed; 
    }); 

    result.reset = function() { 
     initialState(ko.toJSON(root)); 
    }; 

    return result; 
}; 
// add changed flag property to the model 
model.changedFlag = new ko.changedFlag(model); 
// subscribe to changes 
model.changedFlag.isChanged.subscribe(function(isChanged) { 
    if (isChanged) alert("model changed"); 
}); 
ko.applyBindings(model);​ 
3

यह आसान थोड़ा प्लगइन सुंदर आप क्या किया के करीब है, लेकिन यह कई विकल्पों के साथ आता है और बिना आवश्यकताओं की एक बहुत व्यापक सेट पर काम कर सकते हैं मैपिंग प्लगइन की आवश्यकता है:

https://github.com/ZiadJ/knockoutjs-reactor

असल में यह आपको इस प्रकार का कोड लिखने की अनुमति देता है:

ko.watch(viewModel, function(target, trigger) { 
    // do work 
}); 
संबंधित मुद्दे