用户在界面输入的数据可能不适合应用系统。在Flex应用程序中,可以使用validator来确保表单里的字段值满足某些标准。例如,你可以使用validator来确定用户输入有效的电话号码,确定字符串大于最小长度,确定有长编码包含正确的数字。
在典型的client-server环境中,数据校验发生在服务器端,在数据被从服务器提交以后。一个使用Flexvalidator的优点是在客户端执行,这使你在向服务器传输之前校验数据。通过使用Flex validators,你不需要传输数据,然后从服务器端接受错误信息,也全面提高的应用程序的响应度。
注意:Flex validators不是不需要在服务器端执行数据校验,而提供在客户端执行校验的机制来提高应用程序的性能。
Flex包含一系列的validators对于用户输入的公共的数据类型,例如邮政编码,电话号码,信用卡号码。
通过校验标记,例如<mx:EmailValidator>或者<mx:PhoneNumberValidator> ,Validators使用下边连个属性来指定需要校验的元素。
- source:指定一个对象,这个对象包含需要校验的属性。设置它为一个组件实例或数据模型。你需要使用数据绑定语法在MXML中,来指定source属性的值。
- property:一个字符串,他指定了源的属性名。这个属性支持点分割字符串来指定嵌套的属性。
你可以通过下边的方式设置它们的属性:
- 在MXML中使用validator标签
- 在ActionScript中为属性赋值
- 调用Validator.validate()方法来调用 validator执行
简单的添加validators到form里,并且使用他们的默认行为没有提供最有用的经验,但客户端的校验总比没有好。客户端校验的最佳实践(本节)示范了如何使用validator来创建一个对用户更有用的用户体验。
在MXML中创建一个简单的校验器
使用<mx:Validator>标签在MXML中声明一个校验器,或者其他适合的校验标签,例如,声明标准的 电话号码校验器使用<mx:PhonNumberValidator>标记。
Flex validator的默认行为是监听组件上的valueCommit时间。在Flex中,称引起validator运行的事件为触发器。
注意:使用validator的默认触发器导致的行为在Best pratices for client-side validation(本节)是这样的:只有用户离开控件时才会受到校验的反馈。要马上得到反馈,你可以手工触发校验对change事件而不实 valueCommit时间做出反应。Best pratices for client-side validation(本节)本节会对如何实现这个功能给出详细的描述。
例子
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
viewSourceURL="src/ValidationSimpleMXML/index.html"
width="500" height="200"
>
<!--
Validators
-->
<!-- Name must be longer than 2 characters long -->
<mx:StringValidator
id="nameValidator"
source="{nameInput}"
property="text"
minLength="2"
/>
<!-- Validate phone number -->
<mx:PhoneNumberValidator
id="phoneValidator"
source="{phoneInput}" property="text"
/>
<!-- Validate email -->
<mx:EmailValidator
id="emailValidator"
source="{emailInput}" property="text"
/><!--
User interface
-->
<mx:Panel title="Phone number validator">
<mx:Form>
<mx:FormItem label="Name:">
<mx:TextInput
id="nameInput"
/>
</mx:FormItem>
<mx:FormItem label="Phone: ">
<mx:TextInput
id="phoneInput"
/>
</mx:FormItem>
<mx:FormItem label="Email: ">
<mx:TextInput
id="emailInput"
/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
</mx:Application>
运行结果
在ActionScript中创建一个简单的校验
在ActionScript中声明校验器(validator),在MXML文件中的脚本块中,或者在ActionScript文件中,正如下边的例子所示:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
viewSourceURL="src/ValidationSimpleActionScript/index.html"
width="500" height="200"
creationComplete="creationCompleteHandler();"
>
<mx:Script>
<![CDATA[
import mx.validators.StringValidator;
import mx.validators.PhoneNumberValidator;
import mx.validators.EmailValidator;
private var nameValidator:StringValidator;
private var phoneValidator:PhoneNumberValidator;
private var emailValidator:EmailValidator;
private function creationCompleteHandler():void
{
//
// Create validators
//
// Name validator
//(string must be two characters or longer)
nameValidator = new StringValidator();
nameValidator.source = nameInput;
nameValidator.property = "text";
nameValidator.minLength = 2;
// Phone validator
phoneValidator = new PhoneNumberValidator();
phoneValidator.source = phoneInput;
phoneValidator.property = "text";
// Email validator
emailValidator = new EmailValidator();
emailValidator.source = emailInput;
emailValidator.property = "text";
}
]]>
</mx:Script>
<!--
User interface
-->
<mx:Panel title="Phone number validator">
<mx:Form>
<mx:FormItem label="Name:">
<mx:TextInput
id="nameInput"
/>
</mx:FormItem>
<mx:FormItem label="Phone: ">
<mx:TextInput
id="phoneInput"
/>
</mx:FormItem>
<mx:FormItem label="Email: ">
<mx:TextInput
id="emailInput"
/>
</mx:FormItem>
</mx:Form>
</mx:Panel>
</mx:Application>
运行结果
客服端校验的最佳实践
Flex提供几种数据校验的方式。这个快速入门介绍了一个提供最佳客户体验的数据校验方法。
有用的校验方法必须最低限度的也要支持富因特网应用程序的用户界面设计原则。
1.防患于未然,而不是事后责备。
校验错误的表单不应该被用户提交。防止,不责骂原则的意思是,能够准确无误的放置用户犯错误,那么就应该那么做,而不是允许他们犯错误,而事后责备他们。
当做客户端校验时,明显的违反这一原则的情况是,当用户已经提交完整个表单以后,校验用户的输入数据。在Flex应用程序中,你可以创建一个行为,触发校验器,相应表单上提交按钮的单击事件。
2.马上给出反馈
用户操作控件时应该能够得到即时的反馈。当控件值变为有效时,用户应该收到正确的反馈。当控件值变为无效时应该得到错误的反馈。当用户离开控件时给出用户反馈,也非凡上一条原则。
当控件没有给出用户即时反馈,用户只有在离开控件时才能发现错误。要更正错误,用户需要返回控件,因此会花费更多的努力。(这个例子也违反了另一个相关的原则:考虑用户的操作)。更重要的,当用户编一个一个校验错误的输入框的值,用户不知道是否用户的改变会使控件值生效。用户需要离开控件才能知道结果,并且如果依然不合法则需要返回控件继续改变它。
默认的Flex校验器的行为监听valueCommit事件。这导致行为描述就像刚才的那样,只有当用户离开控件以后才能收到反馈。为了给出即时反馈,你必须手工指定触发校验响应change事件,而不是valueCommit事件。
前边的的连个例子展示了没有即时反馈的客户体验。
3.让用户工作
虽然给出即时提示是好事情,你的应用程序在一定程度上,还应该做到不中断用户工作流程。漂浮提示框不中断用户,通常是最好的玄色。只有当完全必要的时候,才能够使用完全中断用户操作的模式对话窗口。
4.验证有罪之前,都是清白的
只有用户与控件交互以后,用户在校验失败后应该给出警告。(换句话说,初始状态,和初始化控件时不应该运行校验并显示校验信息。类似的,重置表单应该移除所有校验错误信息。
连接:设计web应用程序用户界面更多的信息,请查看Aral Balken的著作《User Interface Design Principles for Web Applications》
有用的客户端校验的例子
下边的例子示例了在Flex3中创建校验的最佳实践。它遵循了上文所述的4个用户界面设计的原则。用户在验证有罪之前是清白的,初始的表单上没有校验错误信息,当表单被清除。用户马上可以收到信息当控件值变得可用(给出即时反馈)并且放置用户提交一个错误表单(放置,不是时候责备)。校验错误信息显示为漂浮提示框并且这样可以在不中断用户操作的情况下引导用户填写正确的信息。
- 两个标志,formIsValid和formIsEmpty跟踪当前表单的状态。Submit按钮的enabled属性被绑定在 formIsValid标志,因此,放置用户提交无效的表单。类似的,绑定Clear form按钮的enabled属性到fromIsEmpty标志上,以便只有用户输入过信息之后此按钮才有效。
- focussedFormControl属性持有最后一个发送change事件的引用(换句话说,是用户当前所在的控件)。 validate()帮助方法使用这个属性来指定只显示当前控件的校验错误消息。这很重要,可以防止没有与用户交互的组件的错误信息显示出来。
- 当表单控件的值被改变时,validateForm()事件处理方法使用validate()帮助方法来校验所有的表单控件。只有当所有校验器校验成功,formIsValid标志的值被这是为true然后用户允许提交表单。
- resetFocus()方法调用FocusManager的setFocus方法来将焦点放置于表单的第一个元素。当表单被第一次载入和后来的当表单被用户清空时,resetFocus()方法被调用。将焦点至于第一个控件,可以节省用户的点击次数,。
注意:由于浏览器处理Flash内容的限制,用户必须在Flash应用程序上点击一次才能将焦点移入到Web页面的flash程序中。
- clearFormHandler方法清楚表单控件的值,并且也重置validator到恰当的状态。
例子
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
viewSourceURL="src/ValidationUsable/index.html"
width="500" height="250"
defaultButton="{submitButton}"
creationComplete="creationCompleteHandler();"
>
<mx:Script>
<![CDATA[
import mx.validators.Validator;
import mx.events.ValidationResultEvent;
import mx.controls.Alert;[Bindable]
public var formIsValid:Boolean = false;[Bindable]
public var formIsEmpty:Boolean = true;
// Holds a reference to the currently focussed
// control on the form.
private var focussedFormControl:DisplayObject;
// Validate the form
private function validateForm(event:Event):void
{
// Save a reference to the currently focussed form control
// so that the isValid() helper method can notify only
// the currently focussed form control and not affect
// any of the other form controls.
focussedFormControl = event.target as DisplayObject;// Mark the form as valid to start with
formIsValid = true;// Check if form is empty
formIsEmpty = (nameInput.text == "" && emailInput.text == ""
&& phoneInput.text == "");// Run each validator in turn, using the isValid()
// helper method and update the value of formIsValid
// accordingly.
validate(nameValidator);
validate(phoneValidator);
validate(emailValidator);
}
// Helper method. Performs validation on a passed Validator instance.
// Validator is the base class of all Flex validation classes so
// you can pass any validation class to this method.
private function validate(validator:Validator):Boolean
{
// Get a reference to the component that is the
// source of the validator.
var validatorSource:DisplayObject = validator.source as DisplayObject;
// Suppress events if the current control being validated is not
// the currently focussed control on the form. This stops the user
// from receiving visual validation cues on other form controls.
var suppressEvents:Boolean = (validatorSource != focussedFormControl);
// Carry out validation. Returns a ValidationResultEvent.
// Passing null for the first parameter makes the validator
// use the property defined in the property tag of the
// <mx:Validator> tag.
var event:ValidationResultEvent = validator.validate(null, suppressEvents);
// Check if validation passed and return a boolean value accordingly.
var currentControlIsValid:Boolean = (event.type == ValidationResultEvent.VALID);
// Update the formIsValid flag
formIsValid = formIsValid && currentControlIsValid;
return currentControlIsValid;
}
// Event handler: Gets called when all child components
// have been created.
private function creationCompleteHandler():void
{
// Set the focus on the first field so
// user does not have to mouse over to it.
// Note that the user still has to click on the
// Flex application to give it focus. This is
// a currently limitation in Flex.
resetFocus();
}
// Submit form if everything is valid.
private function submitForm():void
{
Alert.show("Form Submitted!");
}
// Clear the form and reset validation.
private function clearFormHandler():void
{
// Clear all input fields.
nameInput.text = "";
phoneInput.text = "";
emailInput.text = "";
// Clear validation error messages.
nameInput.errorString = "";
phoneInput.errorString = "";
emailInput.errorString = "";
// Flag that the form is now clear
formIsEmpty = true;
// Set the focus on the first field so
// user does not have to mouse over to it.
resetFocus();
}
// Helper method. Sets the focus on the first field so
// user does not have to mouse over to it.
private function resetFocus():void
{
focusManager.setFocus(nameInput);
}
]]>
</mx:Script><!--
Validators
-->
<!-- Name must be longer than 2 characters long -->
<mx:StringValidator
id="nameValidator"
source="{nameInput}"
property="text"
minLength="2"
/>
<!-- Validate phone number -->
<mx:PhoneNumberValidator
id="phoneValidator"
source="{phoneInput}" property="text"
/>
<!-- Validate email -->
<mx:EmailValidator
id="emailValidator"
source="{emailInput}" property="text"
/><!--
User interface
-->
<mx:Panel title="Phone number validator">
<mx:Form>
<mx:FormItem label="Name:">
<mx:TextInput
id="nameInput"
change="validateForm(event);"
/>
</mx:FormItem>
<mx:FormItem label="Phone: ">
<mx:TextInput
id="phoneInput"
change="validateForm(event);"
/>
</mx:FormItem>
<mx:FormItem label="Email: ">
<mx:TextInput
id="emailInput"
change="validateForm(event);"
/>
</mx:FormItem>
</mx:Form>
<mx:ControlBar horizontalAlign="center">
<mx:Button
id="submitButton"
label="Submit"
enabled="{formIsValid}"
/>
<mx:Button
label="Clear form"
enabled="{!formIsEmpty}"
click="clearFormHandler();"
/>
</mx:ControlBar>
</mx:Panel></mx:Application>