Это сообщение довольно длинное, поэтому я подумал: " отвечает " на мой вопрос с решением, а не " редактирование "Вопрос для показа решения был наиболее уместным.Я буду редактировать вопрос, чтобы точнее отразить параметры проблемы (т. Е. Требование, чтобы решение не включало какую-либо дополнительную среду Flex, такую как Cairngorm или PureMVC , чтобы оставаться простым).
Я также допускаю, что это решение немного слабое.На данный момент у меня есть еще одно событие, которое мне нужно выяснить и удалить - , но оно работает и соответствует бизнес / техническим требованиям.Это также чувствовало, как будто я "заново изобретал колесо", и я предпочел бы не.Так что, если у кого-то есть пример (какой-то шаблон проектирования?), Который включает «проверку клиента и сервера», а также использование инфраструктуры проверки Flex для некоторых изменений в itemEditor
(мне нужно редактирование ячейки DataGrid ), Я был бы очень признателен, если бы вы перечислили его здесь в качестве ответа, и, возможно, я могу предложить вам несколько баллов!
Я также не совсем уверен в том, как я закрываю / совершаюредактор.Я пытался использовать destroyItemEditor()
, но мне это не помогло.
Вот мой исходный код:
MyPage.mxml
<?xml version="1.0" encoding="utf-8"?>
<mx:Panel xmlns:mx="http://www.adobe.com/2006/mxml"
xmlns:validators="validators.*"
preinitialize="myPage_preinitializeHandler(event)"
initialize="myPage_initializeHandler(event)"
creationComplete="myPage_creationCompleteHandler(event)">
<mx:Script>
<![CDATA[
import entities.MyModel;
import entities.MyUser;
import events.MyValidatorEvent;
import mx.collections.ArrayCollection;
import mx.controls.TextInput;
import mx.events.DataGridEvent;
import mx.events.DataGridEventReason;
import mx.events.FlexEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.mxml.RemoteObject;
import services.UserRemoteObjectService;
import validators.UserValidator;
private var _userValidator:UserValidator;
private var _securedPageService:RemoteObject;
private var _securedUsersService:RemoteObject;
private var _userRemoteObjectService:UserRemoteObjectService;
[Bindable]
private var _myModelList:ArrayCollection;
protected function myPage_preinitializeHandler(event:FlexEvent):void
{
_userValidator = new UserValidator();
_myModelList = new ArrayCollection();
}
protected function myPage_initializeHandler(event:FlexEvent):void
{
_securedPageService = new RemoteObject();
_securedPageService.destination = "securedPageService";
_securedPageService.getAllData.addEventListener("result",getAllData_resultHandler);
_securedUsersService = new RemoteObject();
_securedUsersService.destination = "securedUsersService";
// For client-side and server-side validation using a RemoteObject service
_userRemoteObjectService = new UserRemoteObjectService(_securedUsersService);
_userValidator.userService = _userRemoteObjectService;
}
protected function myPage_creationCompleteHandler(event:FlexEvent):void
{
initializeModelList();
}
private function initializeModelList():void
{
_securedPageService.getAllData();
}
private function getAllData_resultHandler(event:ResultEvent):void
{
var untypedList:ArrayCollection = (event.result as ArrayCollection);
var myModel:MyModel;
for each(var m:Object in untypedList)
{
myModel = new MyModel(m.auditModelId, m.groupName,
m.reviewRequired, m.fieldNeedingValidation, m.lastReview)
_myModelList.addItem(myModel);
}
}
private function verifyInputIsValid(dgEvent:DataGridEvent):void
{
if (dgEvent.reason == DataGridEventReason.CANCELLED)
{
return; // Edit is "cancelled", do not update
}
// For the fieldNeedingValidation column only
if(dgEvent.dataField == "fieldNeedingValidation") {
// Get the new data value from the editor.
var userID:String = TextInput(dgEvent.currentTarget.itemEditorInstance).text;
_userValidator.addEventListener("totallyComplete",userValidator_completeHandler);
_userValidator.addEventListener("error",userValidator_errorHandler);
_userValidator.validateSystemUser(userID, myPageGrid.itemEditorInstance, dgEvent);
}
}
private function userValidator_completeHandler(event:MyValidatorEvent):void
{
TextInput(event.target.itemEditorInstance).errorString = "";
event.target.dataGridEvent.itemRenderer.data.fieldNeedingValidation = (event.myUser as MyUser).fullName;
myPageGrid.editedItemPosition = null;
myPageGrid.selectedIndex = -1;
}
private function userValidator_errorHandler(event:MyValidatorEvent):void
{
// Prevent the user from removing focus, and leave the cell editor open.
// The edit will not continue and store the blank value
(event.target.dataGridEvent as DataGridEvent).preventDefault();
// Write a message to the errorString property.
// This message appears when the user mouses over the editor.
TextInput(event.target.itemEditorInstance).errorString = event.errorMessage;
return;
}
]]>
</mx:Script>
<mx:Panel title="My Page">
<mx:DataGrid id="myPageGrid" dataProvider="{_myModelList}"
itemEditEnd="verifyInputIsValid(event)" editable="true">
<mx:columns>
<mx:DataGridColumn dataField="someField" headerText="Something" editable="false" />
<mx:DataGridColumn dataField="fieldNeedingValidation" editable="true" headerText="Input User ID"/>
</mx:columns>
</mx:DataGrid>
</mx:Panel>
</mx:Panel>
UserValidator.as
package validators {
import entities.IMyUser;
import entities.MyUser;
import events.MyValidatorEvent;
import flash.events.Event;
import mx.controls.TextInput;
import mx.controls.listClasses.IListItemRenderer;
import mx.events.DataGridEvent;
import mx.events.ValidationResultEvent;
import mx.rpc.AsyncToken;
import mx.rpc.Responder;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.validators.ValidationResult;
import mx.validators.Validator;
import services.IUserService;
public class UserValidator extends Validator
{
public var userService:IUserService; //Service delegate to process the remote validation
private var _itemEditor:IListItemRenderer;
private var _dataGridEvent:DataGridEvent;
private var _inputValue:String = null;
public function UserValidator()
{
super();
}
/**
* The "Core Method" of this class. Invokes validation of a userIDToValidate
* and later takes the appropriate action on UI components as need be.
*/
public function validateSystemUser(userIDToValidate:String, itemEditor:IListItemRenderer ,dgEvent:DataGridEvent):void
{
this._dataGridEvent = dgEvent;
this._itemEditor = itemEditor;
var validatorResult:ValidationResultEvent = this.validate(userIDToValidate);
if(validatorResult.type==ValidationResultEvent.INVALID){
if(validatorResult.results[0].errorCode == "validating"){
// Prevent the user from removing focus, and leave the cell editor open.
// Also, the edit will not continue and store the blank value
dgEvent.preventDefault();
// Write a message to the errorString property.
// This message appears when the user mouses over the editor.
TextInput(itemEditor).errorString = validatorResult.message;
trace("Please wait, server is validating...");
return;
}
else{
// A client-side "invalid", handled the same. This time the message
// does not include "Please wait" text
dgEvent.preventDefault();
TextInput(itemEditor).errorString = validatorResult.message;
return;
}
}
else if(validatorResult.type==ValidationResultEvent.VALID){
// Everything was successful, update the UI
TextInput(itemEditor).errorString = "";
TextInput(itemEditor).text = userIDToValidate;
return;
}
}
// Overide this method to start the validation process
override protected function doValidation(value:Object):Array
{
if (_inputValue != String(value)){
_inputValue = String(value);
}
var results:Array = super.doValidation(value); // Call base class doValidation().
if(results.length > 0){
return results; // Return if there are errors.
}
//Business rules for client side validation will determine this
var someErrorCondition:Boolean = false;
if (someErrorCondition == true)
{
results.push(new ValidationResult(true, null, "errorCode", "Error description"));
return results;
}
else{
trace("All client-side validation has passed");
/**
* Call the remote service, return an 'error' indicating server validation
* is pending. The String identifier is meaningless, except to indicate
* that it should be handled differencly by the consumer of the validation.
*/
results.push(new ValidationResult(true, null, "validating",
"Please wait: \nThe server is validating this corpID."));
var token:AsyncToken = this.userService.service_findByID(_inputValue);
token.addResponder(new Responder(userValidator_resultHandler,
userValidator_faultHandler));
return results;
}
}
private function userValidator_resultHandler(re:ResultEvent):void
{
if(re.result.errorMessage == null)
{
var myUser:IMyUser = new MyUser(re.result.corpID,re.result.fullName,re.result.managerFullName);
var validatorCompleteEvent:Event = new MyValidatorEvent("totallyComplete", "", myUser);
this.dispatchEvent(validatorCompleteEvent);
}
else
{
trace("ERROR: Something went wrong in the userValidator_resultHandler");
}
}
/**
* This fault handler is invoked because my Server (via BlazeDS) actually
* returns/throws a custom Exception. This will dispatch an error to it's consumer
* (MyPage.mxml) using the details of that Exception/FaultEvent, used later to populate
* the same UI component as Flex's standard "Validator" (client-side) would.
* @see: http://livedocs.adobe.com/flex/3/html/help.html?content=validators_2.html
*/
private function userValidator_faultHandler(fe:FaultEvent):void
{
var myUser:IMyUser = new MyUser(this._inputValue,null,null);
var errorEvent:Event = new MyValidatorEvent("error", fe.fault.rootCause.message, myUser);
dispatchEvent(errorEvent);
}
public function get itemEditorInstance():IListItemRenderer
{
return _itemEditor;
}
public function get dataGridEvent():DataGridEvent
{
return _dataGridEvent;
}
}
}
UserRemoteObjectService.as
package services
{
import mx.rpc.AsyncResponder;
import mx.rpc.AsyncToken;
import mx.rpc.events.FaultEvent;
import mx.rpc.events.ResultEvent;
import mx.rpc.remoting.mxml.RemoteObject;
public class UserRemoteObjectService implements IUserService
{
private var _userService:RemoteObject;
public function UserRemoteObjectService(userService:RemoteObject)
{
this._userService = userService;
}
public function service_findByID(userID:String):AsyncToken
{
var token:AsyncToken = _userService.findById(userID);
token.addResponder(
new AsyncResponder(findByID_resultHandler,
findByID_faultHandler)
);
return token;
}
private function findByID_resultHandler(event:ResultEvent, token:AsyncToken=null):void
{
event.token.dispatchEvent(event);
}
private function findByID_faultHandler(event:FaultEvent, token:AsyncToken=null):void
{
event.token.dispatchEvent(event);
}
}
}
Итак, это текущий код, @drkstr и @Kyle, который мне интересно посмотретьчто вы думаете.
Спасибо StackOverflow, @drkstr, сегодня вы отметили галочкой «Принят», вы вдохновили мое решение.