云自无心水自闲

天平山上白云泉,云自无心水自闲。何必奔冲山下去,更添波浪向人间!
posts - 288, comments - 524, trackbacks - 0, articles - 6
  BlogJava :: 首页 :: 新随笔 :: 联系 :: 聚合  :: 管理

现在我们将增加验证、格式化和一些其他的功能。
第四次迭代--添加功能
现在我们回过头来看那个单视图的应用,增加一点真实性,我们模拟一下远程服务有一点延时。我们在Delegate中使用flash.utils.setTimeOut来模拟延时。
通常,当远程服务在处理时,UI会展现一个进度条,禁用一部分控件,让用户明白不能再派发新的请求。在我们的例子中在远程服务在处理的时候,我们会禁用“Get Quote”按钮。完成这一点很容易,只需要在Model对象的StockQuote类中增加一个成员isPending,把它定义为一个bool形,这样可以直接应用于绑定。

 

[Bindable]
public  var isPending : Boolean;

 

增加验证
我们现在添加对股票报价的验证功能,对于这一点,我们可以使用mx.validators.StringValidator来完成这一功能。应用中这两个参数共同控制按钮的有效性。这样可以在Model对象中设置一个isValid属性,用于组合这两参数。

private  function validate() :  void
{
    isValid 
=  ( isSymbolValid  &&   ! isPending );
}

isSymbolValid是一个属性,存放StringValidator的结果。
在StockMarketPod.mxml中添加mx:StringValidator这个Tag

< mx:StringValidator 
    
minLength ="2"  triggerEvent ="change"  
    source
="{ symbolTextInput }"  property ="text"
    valid
="stockQuote.validateSymbol( true );"  
    invalid
="stockQuote.validateSymbol( false );" />


从视图中直接调用Model对象不符合MVC原则,因为视图原则上只能派发事件。但在这个例子中,这样已经足够好了。

增加格式化
我们将股票报价以金额的方式进行展示,在StockMarketPod.mxml中增加一个formatter

< mx:CurrencyFormatter 
    
id ="standardEuroFormatter"   
    currencySymbol
="$"  precision ="2" />
将formatter的结果进行绑定
< mx:Label  text ="{ standardEuroFormatter.format( stockQuote.lastStockQuote ) }" />


现在看一下完整的StockQuote类

package  com.adobe.cairngorm.samples.dashboard.model
{
    
public   class  StockQuote
    
{
        [Bindable]
        
public  var lastStockQuote : Number;
        [Bindable]
        
public  var isValid : Boolean;
        [Bindable]
        
public  var statusMessage : String;
                
        
private  var _isPending : Boolean;
        
private  var isSymbolValid : Boolean;
                
        [Bindable]
        
public  function get isPending() : Boolean
        
{
            
return  _isPending;
        }

        
        
public  function set isPending( value : Boolean ) :  void
        
{
            _isPending 
=  value;
            validate();
        }

            
        
public  function validateSymbol( isValid : Boolean ) :  void
        
{
            isSymbolValid 
=  isValid;
            validate();
        }

        
        
private  function validate() :  void
        
{
            isValid 
=  ( isSymbolValid  &&   ! isPending );
        }
        
    }

}

其中isPending属性的值由GetStockQuoteCommand控制

private  var model : ModelLocator  =  ModelLocator.getInstance();
private  var stockQuote : StockQuote  =  model.stockQuote;
         
public  function execute( event : CairngormEvent ) :  void
{
    stockQuote.isPending 
=   true ;
             
    var stockQuoteEvent : GetStockQuoteEvent 
=  GetStockQuoteEvent( event );          
    var symbol : String 
=  stockQuoteEvent.symbol;
    var delegate : StockMarketDelegate 
=   new  StockMarketDelegate(  this  );
    delegate.getQuoteForSymbol( symbol );    
}

        
public  function onResult( event :  *   =   null  ) :  void
{
    
// for demo purpose: event would normally be an event object of remote service result.            
    stockQuote.lastStockQuote  =  event as Number;            
    stockQuote.isPending 
=   false ;
    stockQuote.statusMessage 
=   "" ;
}

        
public  function onFault( event :  *   =   null  ) :  void
{
    stockQuote.lastStockQuote 
=  NaN;
    stockQuote.statusMessage 
=   " Quote retrieval error. " ;
    stockQuote.isPending 
=   false ;
}

最后看一下StockMarketPod.mxml的全部代码

<? xml version="1.0" encoding="utf-8" ?>
< mx:Panel 
    
xmlns:mx ="http://www.adobe.com/2006/mxml"
    xmlns:util
="com.adobe.cairngorm.samples.dashboard.util.*" >
        
    
< mx:Script >
        
<![CDATA[
            import com.adobe.cairngorm.control.CairngormEventDispatcher;
            import com.adobe.cairngorm.samples.dashboard.model.StockQuote;
            import com.adobe.cairngorm.samples.dashboard.events.GetStockQuoteEvent;    
            
            [Bindable]
            public var stockQuote : StockQuote;
            
            private function getQuoteForSymbol() : void
            {
                var event : GetStockQuoteEvent = new GetStockQuoteEvent( symbolTextInput.text );
                CairngormEventDispatcher.getInstance().dispatchEvent( event );
            }
        
]]>
    
</ mx:Script >
    
    
< mx:CurrencyFormatter 
                
id ="standardEuroFormatter"   
        currencySymbol
="$"  precision ="2" />
        
    
< mx:StringValidator 
        
minLength ="2"  triggerEvent ="change"  
        source
="{ symbolTextInput }"  property ="text"
        valid
="stockQuote.validateSymbol( true );"  
        invalid
="stockQuote.validateSymbol( false );" />
    
    
< mx:Form >
    
        
< mx:FormItem  label ="Symbol" >
            
< mx:TextInput 
                
id ="symbolTextInput" />
            
< mx:Button 
                
label ="Get Quote"  
                enabled
="{ stockQuote.isValid }"  
                click
="getQuoteForSymbol();" />
        
</ mx:FormItem >
                
        
< mx:FormItem  label ="Price Quote" >
            
< mx:Label  text ="{ standardEuroFormatter.format( stockQuote.lastStockQuote ) }" />
            
< mx:Label  text ="{ stockQuote.statusMessage }" />
        
</ mx:FormItem >
        
    
</ mx:Form >     
</ mx:Panel >


此视图中我们不需要使用ModelLocator,而是使用StockQuote作为参数传入StockMarketPod.mxml
引用视图的代码

< mx:Script >
    
<![CDATA[
        import com.adobe.cairngorm.samples.dashboard.model.ModelLocator;
        import com.adobe.cairngorm.samples.dashboard.model.StockQuote;
                                    
        [Bindable]
        private var model : ModelLocator = ModelLocator.getInstance();
        [Bindable]
        private var stockQuote : StockQuote = model.stockQuote;    
    
]]>
</ mx:Script >
 
< view:StockMarketPod 
    
stockQuote ="{ stockQuote }"  
    title
="Stockmarket Pod" />

 

只传递需要的信息给视图是一个比较好的做法,而尽量少使用ModelLocator这样的全局变量,这样也使用视图重用性更高。




只有注册用户登录后才能发表评论。


网站导航: