1 // ==========================================================================
  2 // Project:   The M-Project - Mobile HTML5 Application Framework
  3 // Copyright: (c) 2010 M-Way Solutions GmbH. All rights reserved.
  4 //            (c) 2011 panacoda GmbH. All rights reserved.
  5 // Creator:   Dominik
  6 // Date:      29.10.2010
  7 // License:   Dual licensed under the MIT or GPL Version 2 licenses.
  8 //            http://github.com/mwaylabs/The-M-Project/blob/master/MIT-LICENSE
  9 //            http://github.com/mwaylabs/The-M-Project/blob/master/GPL-LICENSE
 10 // ==========================================================================
 11 
 12 m_require('core/utility/logger.js');
 13 
 14 /**
 15  * @class
 16  *
 17  * The observable knows all observers, mainly views, and pushes updates if necessary.
 18  *
 19  * @extends M.Object
 20  */
 21 M.Observable = M.Object.extend(
 22 /** @scope M.Observable.prototype */ {
 23 
 24     /**
 25      * The type of this object.
 26      *
 27      * @type String
 28      */
 29     type: 'M.Observable',
 30 
 31     /**
 32      * List that contains pairs of an observer with an observable. An observer is tightened to one
 33      * observable, but one observable can have multiple observers.
 34      *
 35      * @type Array|Object
 36      */
 37     bindingList: null,
 38 
 39     /**
 40      * Attach an observer to an observable.
 41      *
 42      * @param {String} observer The observer.
 43      * @param {String} observable The observable.
 44      */
 45     attach: function(observer, observable) {
 46         if(!this.bindingList) {
 47             this.bindingList = [];
 48         }
 49         this.bindingList.push({
 50             observer: observer,
 51             observable: observable
 52         });
 53     },
 54 
 55     /**
 56      * Detach an observer from an observable.
 57      *
 58      * @param {String} observer The observer.
 59      */
 60     detach: function(observer) {
 61         /* grep is a jQuery function that finds
 62          * elements in an array that satisfy a certain criteria.
 63          * It works on a copy so we have to assign the "cleaned"
 64          * array to our bindingList.
 65          */
 66         this.bindlingList = $.grep(this.bindlingList, function(value, index) {
 67                 return value.observer !== observer;
 68         });
 69     },
 70 
 71     /**
 72      * Notify all observers that observe the property behind 'key'.
 73      *
 74      * @param {String} key The key of the property that changed.
 75      */
 76     notifyObservers: function(key) {
 77         _.each(this.bindingList, function(entry){
 78             if(key === entry.observable || (entry.observable.indexOf('.') > 0 && entry.observable.indexOf(key) > -1)) {
 79                 entry.observer.contentDidChange();
 80             } else if(key.indexOf('.') > 0 && entry.observable.indexOf(key.substring(0, key.lastIndexOf('.'))) === 0) {
 81                 entry.observer.contentDidChange();
 82             }
 83         });
 84     }
 85 
 86 });