Flex2.0中使用Validator

本文详细介绍了在Flex2.0中如何使用Validator组件进行数据验证,包括定义Validator的方法及其触发条件,并提供了两种不同的实现方式。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

在Flex2.0中, Validator组件的使用方式和1.5中相比, 进行了一些改变, 不再需要定义Model, 可以在Validator属性中直接引用Form成员了.
    <mx:Form id="loginForm">
        
<mx:Text text=" {AtsModelLocator.getInstance().loginFailMessage }" width="80%" color="red"/>
    
        
<mx:FormItem label="Username: " required="true">
            
<mx:TextInput id="username" />
        
</mx:FormItem>

        
<mx:FormItem label="Password: " required="true">
            
<mx:TextInput id="password" />
        
</mx:FormItem>
    
</mx:Form>


    
<mx:ControlBar>
        
<mx:Button id="loginSubmit" label="Login" mouseUp="loginUser()"/>
    
</mx:ControlBar>
    
    
<mx:StringValidator id="userNameValidator" source="{username}" property="text"
        tooShortError
="This string is shorter than the minimum allowed length of 3. " 
        tooLongError
="This string is longer than the maximum allowed length of 20." 
        minLength
="4" maxLength="20"/>

    
<mx:StringValidator id="userPassValidator" source="{password}" property="text"
        tooShortError
="This string is shorter than the minimum allowed length of 6. " 
        tooLongError
="This string is longer than the maximum allowed length of 10." 
        minLength
="4" maxLength="20"/>

这样就定义好了两个Validator, 可以对用户名和用户密码进行校验.
但是怎么使用这两个Validator呢?

我是这样用的:
    <mx:Script>
    
<![CDATA[
        import mx.controls.Alert;
        import mx.events.ValidationResultEvent;
        import mx.validators.ValidationResult;  
            
       import com.ats.vo.LoginVO;
       import com.ats.control.LoginEvent;
       
       import mx.validators;
       
       public 
function loginUser() : void
       {
          
if ( ! modelCheckValid ) {
              modelCheckValid 
= true;
              
return;
          }
           
          
var loginVO : LoginVO = new LoginVO();
          loginVO.username 
= username.text;
          loginVO.password 
= password.text;
            
            
var event : LoginEvent = new LoginEvent( loginVO );
            dispatchEvent( event );
       }
       
       private 
var modelCheckValid : Boolean = true;
    ]]
>
    
</mx:Script>

    
<mx:Form id="loginForm">
        
<mx:Text text=" {AtsModelLocator.getInstance().loginFailMessage }" width="80%" color="red"/>
    
        
<mx:FormItem label="Username: " required="true">
            
<mx:TextInput id="username" />
        
</mx:FormItem>

        
<mx:FormItem label="Password: " required="true">
            
<mx:TextInput id="password" />
        
</mx:FormItem>
    
</mx:Form>


    
<mx:ControlBar>
        
<mx:Button id="loginSubmit" label="Login" mouseUp="loginUser()"/>
    
</mx:ControlBar>
    
    
<mx:StringValidator id="userNameValidator" source="{username}" property="text"
        tooShortError
="This string is shorter than the minimum allowed length of 3. " 
        tooLongError
="This string is longer than the maximum allowed length of 20." 
        minLength
="4" maxLength="20"
        invalid
="modelCheckValid=false"
        trigger
="{loginSubmit}"
        triggerEvent
="mouseDown"/>

    
<mx:StringValidator id="userPassValidator" source="{password}" property="text"
        tooShortError
="This string is shorter than the minimum allowed length of 6. " 
        tooLongError
="This string is longer than the maximum allowed length of 10." 
        minLength
="4" maxLength="20"
        invalid
="modelCheckValid=false"
        trigger
="{loginSubmit}"
        triggerEvent
="mouseDown"/>



为什么这么复杂地在Validator中定义trigger, triggerEvent呢?
原因是这样的: 如果不是在Validator的invalid事件中去设置modelCheckValid这个标志量.
就需要在loginUser()函数中对所有Validator进行判断, 代码会显得比较臃肿复杂.
而且如果需要考虑是否需要一次性显示出所有校验失败的错误.
代码示例:
    <mx:Script>
    
<![CDATA[
        import mx.controls.Alert;
        import mx.events.ValidationResultEvent;
        import mx.validators.ValidationResult;  
            
       import com.ats.vo.LoginVO;
       import com.ats.control.LoginEvent;
       
       import mx.validators;
       
       public 
function loginUser() : void
       {
       
          
var vrEvent : ValidateResultEvent;
          
          
var checkFailed : Boolean = false;
          
          vrEvent 
= userNameValidator.validate();
          
if ( vrEvent.results != null && vrEvent.results.length > 0 ) {
              
// 验证失败
              checkFailed = true;
          }
          
          vrEvent 
= userPassValidator.validate();
          
if ( vrEvent.results != null && vrEvent.results.length > 0 ) {
              
// 验证失败
              checkFailed = true;
          }
          
          
if ( checkFailed ) return;
           
          
var loginVO : LoginVO = new LoginVO();
          loginVO.username 
= username.text;
          loginVO.password 
= password.text;
            
            
var event : LoginEvent = new LoginEvent( loginVO );
            dispatchEvent( event );
       }
       
    ]]
>
    
</mx:Script>

    
<mx:Form id="loginForm">
        
<mx:Text text=" {AtsModelLocator.getInstance().loginFailMessage }" width="80%" color="red"/>
    
        
<mx:FormItem label="Username: " required="true">
            
<mx:TextInput id="username" />
        
</mx:FormItem>

        
<mx:FormItem label="Password: " required="true">
            
<mx:TextInput id="password" />
        
</mx:FormItem>
    
</mx:Form>


    
<mx:ControlBar>
        
<mx:Button id="loginSubmit" label="Login" mouseUp="loginUser()"/>
    
</mx:ControlBar>
    
    
<mx:StringValidator id="userNameValidator" source="{username}" property="text"
        tooShortError
="This string is shorter than the minimum allowed length of 3. " 
        tooLongError
="This string is longer than the maximum allowed length of 20." 
        minLength
="4" maxLength="20"/>

    
<mx:StringValidator id="userPassValidator" source="{password}" property="text"
        tooShortError
="This string is shorter than the minimum allowed length of 6. " 
        tooLongError
="This string is longer than the maximum allowed length of 10." 
        minLength
="4" maxLength="20"/>

这种方法也是可行的.
至于具体使用哪一个, 凭自己的喜好了.
 
<!DOCTYPE html> <html> <head> <meta charset="utf-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1, user-scalable=no"> <title>FOUPK3音乐</title> <style> /* 完整样式重置 */ * { margin: 0; padding: 0; box-sizing: border-box; } body { font-family: Arial, sans-serif; background-color: #f4f4f4; display: flex; flex-direction: column; align-items: center; padding-top: 40px; } .container { width: 90%; max-width: 400px; } h2 { text-align: center; margin-bottom: 20px; color: #333; } .button-group { display: flex; align-items: center; justify-content: center; gap: 8px; margin: 15px 0; } button, select { padding: 8px 12px; border-radius: 4px; border: none; cursor: pointer; font-size: 14px; } button { background-color: #007bff; color: #fff; } button:hover { opacity: 0.9; } #qualitySelect { background-color: #fff; color: #333; min-width: 120px; } audio { width: 100%; margin: 10px 0; } .file-popup { display: none; position: fixed; top: 50%; left: 50%; transform: translate(-50%, -50%); background: #fff; padding: 20px; border-radius: 8px; box-shadow: 0 0 20px rgba(0,0,0,0.1); z-index: 9999; width: 85%; max-width: 350px; } .close-btn { position: absolute; top: 10px; right: 15px; font-size: 20px; cursor: pointer; } .file-list { max-height: 150px; overflow-y: auto; margin: 15px 0; } .file-item { padding: 8px; border-bottom: 1px solid #eee; cursor: pointer; } .file-item:hover { background-color: #f8f9fa; } #playStatus { text-align: center; margin: 10px 0; color: #666; } </style> </head> <body> <div class="container"> <h2>FOUPK3音乐</h2> <!-- 音效选择 --> <div style="text-align: center; margin-bottom: 10px;"> <label for="qualitySelect" style="display: block; margin-bottom: 5px;">音效:</label> <select id="qualitySelect"> <option value="standard">标准音质</option> <option value="高品">高品音质</option> <option value="SQ">SQ音质(VIP)</option> <option value="HQ">HQ音质(VIP)</option> <option value="无损">无损音质(VIP)</option> <option value="您正在使用FOUPK3音乐ROS">ROS音质(VIP)</option> <option value="母带High five">母带Highfive音质(VIP)</option> <option value="SQM1.0">SQM1.0(VIP)</option> <option value="您正在使用FOUPK3音乐SQM2.0全景">SQM2.0全景音效音质(SVIP)</option> </select> </div> <!-- 音频控件 --> <audio id="myAudio" controls></audio> <!-- 操作按钮(图标替换为文字) --> <div class="button-group"> <button id="loopBtn">循环</button> <button id="playBtn">播放</button> <button id="pauseBtn">暂停</button> <button id="prevBtn">上一首</button> <button id="nextBtn">下一首</button> <button id="localBtn">本地音乐</button> </div> <!-- 播放状态 --> <div id="playStatus"></div> </div> <!-- 本地音乐弹窗 --> <div class="file-popup" id="filePopup"> <span class="close-btn" onclick="closePopup()">×</span> <input type="file" id="fileInput" multiple accept="audio/*" style="display: none;"> <div style="text-align: center; margin-bottom: 10px;"> <button onclick="openFilePicker()">选择音乐(最多15首)</button> </div> <div class="file-list" id="fileList"></div> </div> <script> // 核心变量 const myAudio = document.getElementById('myAudio'); const playBtn = document.getElementById('playBtn'); const pauseBtn = document.getElementById('pauseBtn'); const qualitySelect = document.getElementById('qualitySelect'); const localBtn = document.getElementById('localBtn'); const filePopup = document.getElementById('filePopup'); const fileInput = document.getElementById('fileInput'); const fileList = document.getElementById('fileList'); const playStatus = document.getElementById('playStatus'); const loopBtn = document.getElementById('loopBtn'); let audioFiles = []; let currentIndex = 0; let loopMode = 'list'; // list | single | none let isQualityChanging = false; // 基础播放控制 playBtn.addEventListener('click', () => { if(audioFiles.length === 0) { showStatus('请先添加音乐'); return; } myAudio.play(); showStatus(`正在播放:${audioFiles[currentIndex]?.name || '音乐'}`); }); pauseBtn.addEventListener('click', () => { myAudio.pause(); showStatus('已暂停播放'); }); // 音质切换(带状态保持) qualitySelect.addEventListener('change', () => { isQualityChanging = true; const currentTime = myAudio.currentTime; const wasPlaying = !myAudio.paused; showStatus(`切换至 ${qualitySelect.value} 音质`); myAudio.src = ''; myAudio.load(); myAudio.addEventListener('canplay', () => { myAudio.currentTime = currentTime; if(wasPlaying) myAudio.play(); isQualityChanging = false; }, { once: true }); }); // 循环模式切换(文字显示模式) loopBtn.addEventListener('click', () => { loopMode = loopMode === 'list' ? 'single' : loopMode === 'single' ? 'none' : 'list'; updateLoopText(); showStatus(`循环模式:${loopMode === 'list' ? '列表循环' : loopMode === 'single' ? '单曲循环' : '关闭循环'}`); }); // 更新循环按钮文字 function updateLoopText() { switch(loopMode) { case 'list': loopBtn.textContent = '列表循环'; break; case 'single': loopBtn.textContent = '单曲循环'; break; case 'none': loopBtn.textContent = '不循环'; break; } } // 本地音乐功能(保持不变) localBtn.addEventListener('click', () => { filePopup.style.display = 'block'; }); function openFilePicker() { fileInput.click(); } fileInput.addEventListener('change', (e) => { /* 逻辑不变 */ }); function renderFileList() { /* 逻辑不变 */ } function playFile(index) { /* 逻辑不变 */ } function handlePlayEnd() { /* 逻辑不变 */ } function closePopup() { /* 逻辑不变 */ } function showStatus(text, duration = 2000) { /* 逻辑不变 */ } // 上一首/下一首(文字逻辑) document.getElementById('prevBtn').addEventListener('click', () => { if(loopMode === 'single') return; currentIndex = (currentIndex - 1 + audioFiles.length) % audioFiles.length; playFile(currentIndex); }); document.getElementById('nextBtn').addEventListener('click', () => { if(loopMode === 'single') return; currentIndex = (currentIndex + 1) % audioFiles.length; playFile(currentIndex); }); </script> </body> </html> 修复已知错误和问题。
06-08
资源下载链接为: https://pan.quark.cn/s/1bfadf00ae14 华为移动服务(Huawei Mobile Services,简称 HMS)是一个全面开放的移动服务生态系统,为企业和开发者提供了丰富的工具和 API,助力他们构建、运营和推广应用。其中,HMS Scankit 是华为推出的一款扫描服务 SDK,支持快速集成到安卓应用中,能够提供高效且稳定的二维码和条形码扫描功能,适用于商品扫码、支付验证、信息获取等多种场景。 集成 HMS Scankit SDK 主要包括以下步骤:首先,在项目的 build.gradle 文件中添加 HMS Core 库和 Scankit 依赖;其次,在 AndroidManifest.xml 文件中添加相机访问和互联网访问权限;然后,在应用程序的 onCreate 方法中调用 HmsClient 进行初始化;接着,可以选择自定义扫描界面或使用 Scankit 提供的默认扫描界面;最后,实现 ScanCallback 接口以处理扫描成功和失败的回调。 HMS Scankit 内部集成了开源的 Zxing(Zebra Crossing)库,这是一个功能强大的条码和二维码处理库,提供了解码、生成、解析等多种功能,既可以单独使用,也可以与其他扫描框架结合使用。在 HMS Scankit 中,Zxing 经过优化,以更好地适应华为设备,从而提升扫描性能。 通常,ScanKitDemoGuide 包含了集成 HMS Scankit 的示例代码,涵盖扫描界面的布局、扫描操作的启动和停止以及扫描结果的处理等内容。开发者可以参考这些代码,快速掌握在自己的应用中实现扫码功能的方法。例如,启动扫描的方法如下: 处理扫描结果的回调如下: HMS Scankit 支持所有安卓手机,但在华为设备上能够提供最佳性能和体验,因为它针对华为硬件进行了
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值