在講解View類以前,咱們先回顧一下PureMVC的模塊劃分:數組
View.prototype.mediatorMap = null;
咱們知道Mediator類有一個onRegister()方法,當Mediator對象在facade中註冊時調用的,實際上Mediator對象的註冊是經過調用View單例的registerMediator()方法來實現。函數
View.prototype.registerMediator = function(mediator) { if(this.mediatorMap[mediator.getMediatorName()] != null) { return; } //mediator類繼承Notifier類,這是初始化Notifier,給mediator的facade屬性賦值 mediator.initializeNotifier(this.multitonKey); this.mediatorMap[mediator.getMediatorName()] = mediator; //返回mediator感興趣的消息 var interests = mediator.listNotificationInterests(); // register mediator as an observer for each notification if(interests.length > 0) { //建立一個Observer,把notification和mediator關聯起來 var observer = new Observer(mediator.handleNotification, mediator); for(var i = 0; i < interests.length; i++) { this.registerObserver(interests[i], observer); } } //在這裏調用了mediator的onRegister()方法 mediator.onRegister(); }
從這段代碼中能夠明白Mediator類onRegister()方法的調用機制了,這段代碼中還有一個地方須要咱們去深刻研究:this
//這段代碼什麼意思呢?
this.registerObserver(interests[i], observer);
registerObserver(),經過方法名咱們能夠知道它是用來註冊Observer對象的,咱們看一下的實現代碼:spa
View.prototype.registerObserver = function(notificationName, observer) { if(this.observerMap[notificationName] != null) { this.observerMap[notificationName].push(observer); } else { this.observerMap[notificationName] = [observer]; } };
View.prototype.removeObserver = function(notificationName, notifyContext) { //經過notificationName,能夠檢索到接受該消息的Observer,返回一個數組 var observers = this.observerMap[notificationName]; for(var i = 0; i < observers.length; i++) { if(observers[i].compareNotifyContext(notifyContext) == true) { //移除observer observers.splice(i, 1); break; } } if(observers.length == 0) { delete this.observerMap[notificationName]; } };
另外,咱們知道Mediator類還有一個與onRegister()(註冊)方法對應的onRemove()(註銷)方法,是Mediator對象在facade中註銷時調用的,Mediator對象的註銷是經過調用View單例的removeMediator()方法來實現:prototype
View.prototype.removeMediator = function(mediatorName) { var mediator = this.mediatorMap[mediatorName]; if(mediator) { // for every notification the mediator is interested in... var interests = mediator.listNotificationInterests(); for(var i = 0; i < interests.length; i++) { // remove the observer linking the mediator to the notification this.removeObserver(interests[i], mediator); } // remove the mediator from the map delete this.mediatorMap[mediatorName]; //觸發mediator對象的onRemove方法 mediator.onRemove(); } return mediator; };
mediator對象除了在facade中註冊(registerMediator),從facade中註銷(removeMediator),還有一個很重要的方法,就是從facade裏面檢索mediator( retrieveMediator):設計
View.prototype.retrieveMediator = function(mediatorName) { return this.mediatorMap[mediatorName]; };
經過上面的例子,咱們能夠知道Mediator類onRegister(),onRemove()方法的使用原理(與View類的registerMediator(),removeMediator,retrieveMediator()對應)和怎麼註冊觀察者(registerObserver())、怎麼移除觀察者(removeMediator())。View類還有一個重要的方法就是給全部的觀察者發送消息(notifyObservers()),觸發觀察者的消息處理函數。rest
View.prototype.notifyObservers = function(notification) { // SIC if(this.observerMap[notification.getName()] != null) { var observers_ref = this.observerMap[notification.getName()], observers = [], observer for(var i = 0; i < observers_ref.length; i++) { observer = observers_ref[i]; observers.push(observer); } for(var i = 0; i < observers.length; i++) { observer = observers[i]; //出發了觀察者的消息處理函數 observer.notifyObserver(notification); } } };
到目前爲止,咱們應該能夠大體弄清楚mediator對象的消息處理機制了。code
咱們在Mediator/Command/Proxy經過調用繼承自Notifier類的sendNotification()發送消息,其實是調用View單例的notifyObservers()方法。server
View類是個多例類,它用instanceMap來存放View類的實例,咱們來看一下它的構造函數:xml
function View(key) { if(View.instanceMap[key] != null) { throw new Error(View.MULTITON_MSG); }; this.multitonKey = key; View.instanceMap[this.multitonKey] = this; this.mediatorMap = []; this.observerMap = []; this.initializeView(); }; /** * @protected * Initialize the Singleton View instance * * Called automatically by the constructor, this is your opportunity to * initialize the Singleton instance in your subclass without overriding the * constructor * * @return {void} */ View.prototype.initializeView = function() { return; };
View.getInstance = function(key) { if (null == key) return null; if(View.instanceMap[key] == null) { View.instanceMap[key] = new View(key); };
//其實是從instanceMap數組中檢索 return View.instanceMap[key]; };
總結一下,View類的結構相對於Mediator、Command、Proxy類要複雜許多,但他是PureMVC消息機制的核心,裏面的不少方法咱們須要記住,反覆揣摩,特別是notifyObservers()。最後,附上View類的思惟導圖。