關於Flex Cairngorm中command層與View層的通訊及耦合度高的問題的解決

來源:互聯網
上載者:User

在Cairngorm架構中,view層發送自訂事件,command層再根據事件做相應的處理,View層中的資料通過綁定ModelLocator中的屬性實現自動更新。現有的問題是,有時除了更新資料意外,使用者需要更多的資訊,比如,我需要判斷後台返回的資料是否正確,或者,我需要更具返回的資料做下一步的處理。

簡單的例子,如果擷取的資料不符合使用者的需要,我可能需要一個提示框給使用者一個提示。提示框應該屬於View層的。當然在command層也可以直接import  mx.controls.Alert;  調用Alert.show()方法。

但如果,使用者在擷取到資料後,要執行View層的另外一個方法,那就比較棘手了。比如,我需要在view層DataGrid刪除一個資料,我在view層發送一個刪除的事件,command層處理事件會返回一個結果,此時,我在view層就要根據不同的結果往下執行不同方法,比如,失敗了我執行一個doFail()的,成功了我doSuccess()。

command如何讓View去執行下一步的方法呢?

1.傳統的做法(command操縱view的引用)
方法A:將view存入ModelLocator中的屬性中,而後在command就可以拿到該view的引用,從而執行view的方法。
這種方法可行,但view與command的耦合在了一起,嚴重破壞了MVC的松耦合度的要求

private function onResult_delete(e:ResultEvent):void{if (e.result != null){var result:String=e.result.code as String;if (result == "success"){ Alert.show("刪除成功!"); (_model.userManagerModel.view as Object).doSuccess();} }else{Alert.show("修改失敗!");                               (_model.userManagerModel.view as Object).doFail();}}

將view存入ModelLocator的_model.userManagerModel.view中,在command強制轉換為Object從而拿到view的引用

方法B:用到架構中的ViewHelper和ViewLocator這兩個類。
ViewHelper類實現介面IMXMLObject,首先自訂一個ViewHelper,然後在視圖中引用它。
 

package domain.app.view{ import com.adobe.cairngorm.view.ViewHelper; public class LoginViewHelper extends ViewHelper{ public function doSomething(){ //do something with the protected property view. } }} 

 

在視圖中執行個體化這個ViewHelper
<helper:LoginViewHelper id="loginViewHelper"/>
然後就可以在Command中使用這個ViewHelper。

但方法同樣存在耦合度高的問題,故 Cairngorm 3版本中已經廢棄

2.現有做法(事件通訊)
既然Flex基於事件驅動的,既然,view可以發事件給command ,那為什麼command 不可以發事件通知給view呢?
當view監聽到該事件後,自然就可以繼續執行view的其他方法了。那view由誰來做這個command發送過來的事件呢?
此時,CairngormEventDispatcher.getInstance()出場。
首先,在CairngormEvent的子類中MyEvent定義2個事件,一個是處理事件DEL,一個是處理事件的事件DEL_COMPLETE,另外添加一個code變數用來儲存DEL結果

public class MyEvent extends CairngormEvent{public static const DEL:String = "DEL"; //刪除public static const DEL_COMPLETE:String = "DEL_COMPLETE"; //刪除資料  處理完後處理事件/*返回參數類型 "success""exist""fail"*/public var code:String =""; /*事件類型*/public var event_type:String="";public function MyEvent(type:String){this.event_type=type;super(type);}}

其中DEL是交給command處理的,所以要在FrontController中做一個綁定;DEL_COMPLETE則不需要

this.addCommand(MyEvent.DEL, UserManagerCommand);

我們在view發事件DEL給command後,立馬用CairngormEventDispatcher.getInstance()做一個DEL_COMPLETE事件的監聽

command 在處理完DEL後,就發送一個DEL_COMPLETE事件,此時,view在監聽這個事件的CairngormEventDispatcher.getInstance()就可以執行相應的方法了

下面是commad的操作

private function onResult_delete(e:ResultEvent):void{var event:MyEvent = new MyEvent(MyEvent.DEL_COMPLETE);if (e.result != null){var result:String=e.result.code as String;if (result == "success"){ event.code = "success";}else{event.code = "fail"} }else{event.code = "fail"}/*發送處理事件*/event.dispatch();}

 

下面是view的操作

private function init():void{ var e :MyEvent = new MyEvent(MyEvent.DEL);e.dispatch();/* 監聽 資料返回 */CairngormEventDispatcher.getInstance().addEventListener(MyEvent.DEL_COMPLETE, del_compelete);}}/************************************************************** * 函數:command處理完成後執行方法 */private function del_compelete(e:MyEvent):void{CairngormEventDispatcher.getInstance().removeEventListener(MyEvent.EDIT_COMPLETE, del_compelete);if (e.code =="success"){Alert.show("刪除成功!"); doSuccess();} else if (e.code =="fail"){Alert.show("刪除失敗!"); doFail();}}

這樣,view和command耦合性的問題得到解決。

 

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.