2012-09-06 19 views
13

हाय मैं जावास्क्रिप्ट में पर्यवेक्षक पैटर्न लागू करने के लिए tyring हूँ:जावास्क्रिप्ट में पर्यवेक्षक पैटर्न को कैसे कार्यान्वित करें?

मेरे index.js:

$(document).ready(function() { 
    var ironMan = new Movie(); 
    ironMan.setTitle('IronMan'); 
    ironMan.setRating('R'); 
    ironMan.setId(1); 
    // ironMan.setCast(['Robert Downey Jr.', 'Jeff Bridges', 'Gwyneth Paltrow']); 

    var terminator = new Movie(); 
    terminator.setTitle('Terminator'); 
    terminator.setRating('P'); 
    terminator.setId(2); 

    console.log(ironMan.toString()); 
    console.log(terminator.toString()); 

    ironMan.play(); 
    ironMan.stop(); 
    ironMan.download(); 
    ironMan.share('V. Rivas'); 

    console.log(ironMan.getCast()[0]); 
}); 

मेरे फिल्म:

var title; 
var rating; 
var id; 
var observers; 


function Movie() { 
    observers = new ObserverList(); 
} 

//function Movie (title, rating, id){ 
// this. title = title; 
// this.rating = rating; 
// this.id =id; 
// observers = new ObserverList(); 
//} 

Movie.prototype.setTitle = function (newTitle) { 
    this.title = newTitle; 
} 

Movie.prototype.getTilte = function() { 
    return this.title; 
} 

Movie.prototype.setRating = function (newRating) { 
    this.rating = newRating; 
} 

Movie.prototype.getRating = function() { 
    return this.rating; 
} 

Movie.prototype.setId = function (newId) { 
    this.id = newId; 
} 

Movie.prototype.getId = function() { 
    return this.id; 
} 

Movie.prototype.play = function() { 
    for (i = 0; i < observers.Count; i++) { 
    console.log("palying..."); 
    } 
} 

Movie.prototype.stop = function() { 
    for (i = 0; i < observers.Count; i++) { 
    console.log("stoped"); 
    } 
} 

Movie.prototype.AddObserver = function (observer) { 
    observers.Add(observer); 
}; 

अंत में पर्यवेक्षक:

function ObserverList() { 
    this.observerList = []; 
} 

ObserverList.prototype.Add = function (obj) { 
    return this.observerList.push(obj); 
}; 

ObserverList.prototype.Empty = function() { 
    this.observerList = []; 
}; 

ObserverList.prototype.Count = function() { 
    return this.observerList.length; 
}; 

ObserverList.prototype.Get = function (index) { 
    if (index > -1 && index < this.observerList.length) { 
    return this.observerList[index]; 
    } 
}; 

ObserverList.prototype.Insert = function (obj, index) { 
    var pointer = -1; 

    if (index === 0) { 
    this.observerList.unshift(obj); 
    pointer = index; 
    } else if (index === this.observerList.length) { 
    this.observerList.push(obj); 
    pointer = index; 
    } 

    return pointer; 
}; 

कोई भी सहायता जो आप प्रदान कर सकते हैं मुझे सबसे ज्यादा आभारी होंगे।

उत्तर

12

जावास्क्रिप्ट में, जावा में शुद्ध पर्यवेक्षक पैटर्न को लागू करने का कोई मतलब नहीं है, क्योंकि जावास्क्रिप्ट में इस छोटी सी चीज को कार्यात्मक प्रोग्रामिंग कहा जाता है। तो बस अपने पर्यवेक्षक सूची के बजाय http://api.jquery.com/category/callbacks-object/ जैसे कुछ का उपयोग करें।

यदि आप अभी भी अपनी वस्तु का उपयोग करना चाहते हैं, तो सब कुछ इस बात पर निर्भर करता है कि आप पर्यवेक्षक सूची में क्या करना चाहते हैं। जोड़ें। यदि यह किसी वस्तु है, तो आप

for(i = 0; i < observers.Count; i++) { 
    observers[i].Notify("some data"); 
} 

लिखने के लिए यदि यह एक समारोह तो आप

for(i = 0; i < observers.Count; i++) { 
    observers[i]("Some data"); 
} 

इसके अलावा, आप Function.apply() या Function.call उपयोग कर सकते हैं लिखने की ज़रूरत है() की आवश्यकता this को अपने फ़ंक्शन

+0

मैं इसे बाहर की जाँच करेंगे, लेकिन अगर मैं इसे काम करना चाहता था जैसा कि है, मैं क्या shoudl करता हूँ? –

+1

उत्तर –

+0

उत्तर अद्यतन दिमित्री, मुझे जोड़ने के लिए कहां करना चाहिए? और मुझे किस का उपयोग करना चाहिए? पर्यवेक्षक वर्ग या फिल्म वर्ग में से एक? बहुत बहुत धन्यवाद –

28

जावास्क्रिप्ट ईवेंट संचालित: इसका मतलब है कि यह समय के बारे में पता है और समय के साथ चीजों को बदलने की अपेक्षा करता है। मूल पर्यवेक्षक पैटर्न सी ++ जैसी भाषाओं के लिए बनाया गया था जो समय के बारे में नहीं जानते हैं। राज्य परिवर्तनों की जांच के लिए गेम लूप का उपयोग करके आप जावास्क्रिप्ट की ताकत का लाभ उठा सकते हैं।

दो डोम तत्वों, एक इनपुट और आउटपुट

<input type="text" value="Enter some text..."> 
<p id="output"> 

एक requestAnimationFrame पाश सेट करें और अवलोकन शुरू बनाएँ।

//Get a reference to the input and output 
var input = document.querySelector("input"); 
var output = document.querySelector("#output"); 

//Set up a requestAnimationFrame loop 
function update() { 
    requestAnimationFrame(update); 

    //Change the output to match the input 
    output.innerHTML = input.value; 
} 
update(); 

यह वही खेल इंजन तत्काल मोड प्रतिपादन के लिए करते हैं। डीओएम में राज्य परिवर्तनों की जांच करने के लिए प्रतिक्रिया ढांचा भी यही करता है।

(आप इसे की जरूरत है, यहाँ है एक सरल requestAnimationPolyfill)

//Polyfill for requestAnimationFrame 
window.requestAnimationFrame = (function(){ 
    return window.requestAnimationFrame  || 
      window.webkitRequestAnimationFrame || 
      window.mozRequestAnimationFrame || 
      window.oRequestAnimationFrame  || 
      window.msRequestAnimationFrame  || 
      function(/* function */ callback, /* DOMElement */ element){ 
      window.setTimeout(callback, 1000/60); 
      }; 
})(); 
3

यहाँ जावास्क्रिप्ट में पर्यवेक्षक पैटर्न है कि बहुत Backbone Models के समान एक API प्रदान करता है के एक कार्यान्वयन है। यह कार्यान्वयन suggested by Douglas Crockford के रूप में "यह" और "नया" के उपयोग से बचाता है।

// The constructor function. 
function Model(){ 

    // An object containing callback functions. 
    // * Keys are property names 
    // * Values are arrays of callback functions 
    var callbacks = {}, 

     // An object containing property values. 
     // * Keys are property names 
     // * Values are values set on the model 
     values = {}; 

    // Return the public Model API, 
    // using the revealing module pattern. 
    return { 

    // Gets a value from the model. 
    get: function(key){ 
     return values[key]; 
    }, 

    // Sets a value on the model and 
    // invokes callbacks added for the property, 
    // passing the new value into the callback. 
    set: function(key, value){ 
     values[key] = value; 
     if(callbacks[key]){ 
     callbacks[key].forEach(function (callback) { 
      callback(value); 
     }); 
     } 
    }, 

    // Adds a callback that will listen for changes 
    // to the specified property. 
    on: function(key, callbackToAdd){ 
     if(!callbacks[key]){ 
     callbacks[key] = []; 
     } 
     callbacks[key].push(callbackToAdd); 
    }, 

    // Removes a callback that listening for changes 
    // to the specified property. 
    off: function(key, callbackToRemove){ 
     if(callbacks[key]){ 
     callbacks[key] = callbacks[key].filter(function (callback) { 
      return callback !== callbackToRemove; 
     }); 
     } 
    } 
    }; 
} 

यहाँ का उपयोग करता है मॉडल कुछ उदाहरण कोड है:

// Create a new model. 
var model = Model(); 

// Create callbacks for X and Y properties. 
function listenX(x){ 
    // The new value is passed to the callback. 
    console.log('x changed to ' + x); 
} 

function listenY(y){ 
    // The new value can be extracted from the model. 
    console.log('y changed to ' + model.get('y')); 
} 

// Add callbacks as observers to the model. 
model.on('x', listenX); 
model.on('y', listenY); 

// Set values of X and Y. 
model.set('x', 30); // prints "x changed to 30" 
model.set('y', 40); // prints "y changed to 40" 

// Remove one listener. 
model.off('x', listenX); 
model.set('x', 360); // prints nothing 
model.set('y', 50); // prints "y changed to 40" 
+0

यह ऑब्जेक्ट शाब्दिक पैटर्न है। खुलासा मॉड्यूल पैटर्न के लिए, दोनों कार्य प्राप्त होते हैं, सेट को बंद करने में परिभाषित किया जाएगा, और आप फॉर्म 'रिटर्न {get: get, set: set};' –

+0

के अंत में एक ऑब्जेक्ट वापस कर सकते हैं आपका समाधान अधिक प्रकाशित है सदस्यता सदस्यता पैटर्न https://en.wikipedia.org/wiki/Publish%E2%80%93subscribe_pattern –

1

मुझे इस के लिए जे एस में एक पर्यवेक्षक पैटर्न लागू करने के लिए सबसे अच्छा तरीका है

function Click() { 
    this.handlers = []; // observers 
} 

Click.prototype = { 

    subscribe: function(fn) { 
     this.handlers.push(fn); 
    }, 

    unsubscribe: function(fn) { 
     this.handlers = this.handlers.filter(
      function(item) { 
       if (item !== fn) { 
        return item; 
       } 
      } 
     ); 
    }, 

    fire: function(o, thisObj) { 
     var scope = thisObj || window; 
     this.handlers.forEach(function(item) { 
      item.call(scope, o); 
     }); 
    } 
} 

// log helper 

var log = (function() { 
    var log = ""; 

    return { 
     add: function(msg) { log += msg + "\n"; }, 
     show: function() { alert(log); log = ""; } 
    } 
})(); 

function run() { 

    var clickHandler = function(item) { 
     log.add("fired: " + item); 
    }; 

    var click = new Click(); 

    click.subscribe(clickHandler); 
    click.fire('event #1'); 
    click.unsubscribe(clickHandler); 
    click.fire('event #2'); 
    click.subscribe(clickHandler); 
    click.fire('event #3'); 

    log.show(); 
} 
+0

क्या होता है यदि एक ही कार्यक्षमता वाला एक श्रोता संलग्न किया जा रहा है? मान लें कि methodA और methodB दोनों एक ही फ़ंक्शन की सदस्यता लेते हैं। – Dementic

0

नीचे एक कार्यान्वयन मैं एक अनुकूलित है पुस्तक सीखना जावास्क्रिप्ट डिजाइन पैटर्न से थोड़ा।

function pubsub(obj) { 

var events = {}, 
    subUid = -1; 

obj.publish = function (event, args) { 

    if (!events[event]) { 
     return false; 
    } 

    var subscribers = events[event], 
    len = subscribers ? subscribers.length : 0; 

    while (len--) { 
     subscribers[len].func(event, args); 
    } 
}; 

obj.subscribe = function (event, func) { 

    if (!events[event]) { 
     events[event] = []; 
    } 

    var token = (++subUid).toString(); 
    events[event].push({ 
     token: token, 
     func: func 
    }); 

    return token; 

}; 

obj.unsubscribe = function (token) { 

    for (var event in events) { 
     if (events.hasOwnProperty(event)) { 
      for (var i = 0, j = events[event].length ; i < j ; i++) { 
       if (events[event][i].token === token) { 
        events[event].splice(i, 1); 
       } 
      } 
     } 
    } 

    return this; 

}; 

} 

var obj = {}; // Any javascript object 
pubsub(obj); // Make an observable from the given object 

var subscription = obj.subscribe('load', handler); 

// event handler callback 
function handler(event, data) { 
    console.log(event, data); 
} 

obj.publish('load', 'Data loaded successfully'); // logs 'load Data loaded successfully' 
obj.unsubscribe(subscription); 
obj.publish('load', 'Data loaded successfully'); // nothing happens 

चीयर्स!

0

पर्यवेक्षक पैटर्न ऑब्जेक्ट को अपडेट करने के बारे में है और उन अपडेट्स को स्वचालित रूप से एक ईवेंट भेजना है जो अद्यतन किया गया था इसके बारे में जानकारी देता है।

उदाहरण के लिए:

function ObserverList(){ 
    this.observerList = [] 
    this.listeners = [] 
} 

ObserverList.prototype.add = function(obj){ 
    this.observerList.push(obj) 
    this.listeners.forEach(function(callback){ 
    callback({type:'add', obj:obj}) 
    }) 
} 

ObserverList.prototype.onChange = function(callback){ 
    this.listeners.push(callback) 
} 

यहाँ जावास्क्रिप्ट में पर्यवेक्षक पैटर्न के एक मॉड्यूल है, तो आप और अधिक जानकारी सामने स्रोत कोड पर एक नज़र ले जा सकते हैं: https://github.com/Tixit/observe