Flex: Служба LCDS возвращает нулевой Asynctoken при выполнении во второй раз
Я разрабатываю приложение Flex с использованием RobotLegs, LiveCycle DS & Java. Я пытаюсь реализовать функцию обновления, используя LCDS, но у меня странное поведение:
Это код ActionScript в RobotLegs execute
Команда, используемая для выполнения обновления:
var token:AsyncToken = services.requestService.commit(new Array(model.currentRequestDetail));
responder = new AsyncResponder(resultHandler, faultHandler, token);
if ( token ) token.addResponder(responder);
model.currentRequestDetail
Я пытаюсь обновить объект RequestDetail:
[Managed]
[RemoteClass(alias="be.fgov.mobilit.td.lcds.vo.RequestDetail")]
public class RequestDetail {
public var id:Number;
public var request:Request;
public var task:Task;
/**
* Constructor
*/
public function RequestDetail() {
}
}
При первом выполнении кода Actionscript все работает нормально.
As yncToken приятно возвращается services.requestService.commit()
функция resultHandler выполняется, как и ожидалось, и мой объект обновляется в графическом интерфейсе.
Тем не менее, во второй раз этот код выполняется, мой services.requestService.commit()
Функция возвращает нулевое значение, и мой resultHandler никогда не достигается. Я подозреваю, что мы даже не достигли Java-ассемблера.
Вот как я объявил DataService:
var requestDetailService:DataService = new DataService("requestDetail");
requestDetailService.autoCommit = false;
И resultHandler, и faultHandler имеют правильную подпись:
resultHandler(result:Object, token:Object = null)
faultHandler(result:Object, token:Object = null)
Мы также используем пользовательский Java-ассемблер, это код:
package be.fgov.mobilit.td.lcds.assemblers;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import be.fgov.mobilit.td.lcds.vo.RequestDetail;
import flex.data.ChangeObject;
import flex.data.assemblers.AbstractAssembler;
public class RequestAssembler extends AbstractAssembler {
public RequestAssembler() {
// TODO Auto-generated constructor stub
}
public RequestDetail getRequest(Map<String, Object> identity) {
return ServiceUtility.getLcdsService().getRequestDetail(identity);
}
public List<ChangeObject> syncRequest(List<ChangeObject> changes) {
Iterator<ChangeObject> iterator = changes.iterator();
ChangeObject co;
while (iterator.hasNext()) {
co = (ChangeObject) iterator.next();
if (co.isUpdate()) {
co = doUpdate(co);
}
}
return changes;
}
private ChangeObject doUpdate(ChangeObject co) {
RequestDetail requestDetail = (RequestDetail) co.getNewVersion();
co.setNewVersion(ServiceUtility.getLcdsService().updateRequestDetail(requestDetail));
return co;
}
}
Это конфигурация ассемблера:
<destination id="request">
<properties>
<source>be.fgov.mobilit.td.lcds.assemblers.RequestAssembler</source>
<scope>application</scope>
<metadata>
<identity property="id" />
<identity property="task" />
</metadata>
<server>
<get-method>
<name>getRequest</name>
</get-method>
<sync-method>
<name>syncRequest</name>
</sync-method>
</server>
</properties>
</destination>
Короче:
У кого-нибудь есть подсказка / опыт, почему во второй раз я выполняю services.requestService.commit();
функция возвращает нулевой Asynctoken?
Спасибо заранее!
В соответствии с просьбой я добавил (раздетый) код из своего класса услуг. Как видите, ничего особенного не происходит:
package be.fgov.mobilit.services {
import mx.data.DataService;
import mx.messaging.Consumer;
import mx.messaging.events.MessageEvent;
import mx.rpc.http.HTTPService;
public class LiveCycleServices {
public var requestService:DataService;
public function LiveCycleServices() {
requestService = new DataService("request");
requestService.autoCommit = false;
}
/**
* @param MessageEvent The event object that is dispatched by the Flex framework
* @return void
*
* This message captures the server push messages that need to trigger an update
* of the task list, since this is specific for every client and cannot be
* determined on the server side, coming from LiveCycle.
*/
private function messageHandler(event:MessageEvent):void {
taskListService.refresh();
}
}
}
Это выбор, где добавляются мои обработчики результатов и ошибок:
var token:AsyncToken = services.requestService.commit(new Array(model.currentRequestDetail));
var responder:AsyncResponder = new AsyncResponder(resultHandler, faultHandler, token);
if ( token ) token.addResponder(responder);
2 ответа
Aysnctoken возвращает ноль, если у вас нет изменений для фиксации. Надеюсь это поможет.
WWW, Это не совсем ответ как таковой, но мне нужно больше места, чем даст мне комментарий. Однако я не вижу, как весь ваш код связан достаточно хорошо, чтобы дать вам хороший ответ.
В общем, сигнатуры результата и ошибки не должны выглядеть так, как вы описываете как "правильную" сигнатуру. AsyncToken ожидает IResponder, у которого ментоды ошибок и результатов имеют единственный параметр, который является объектом. Как правило, это вызывается при событии сбоя или результата (в зависимости от ситуации).
Теперь я собираюсь на территорию, которая для меня чисто теоретическая. Мне кажется, что класс DataService может создать только один AsyncToken, так как соединение остается открытым. Если это так, возможно, ошибочная сигнатура метода повредит AsyncToken до такой степени, что он не может быть возвращен для использования методом. В коде, который вы вставили, я не увидел ничего похожего на то, что он вызывает ваши методы результата и ошибки по-своему.
Я сильно сомневаюсь, что проблема в коде Java. AFAIK, AsyncToken создается и настраивается для вызова функций в ответчике еще до того, как будет выполнен вызов (по крайней мере, именно так он работает с HTTPService или amf). Я ожидаю, что есть некоторая ошибка, которая "услужливо" подавляется, так что вы могли бы выиграть от пошагового выполнения кода.
Я бы посоветовал вам сделать шаг назад и немного более внимательно взглянуть на "S" часть архитектуры MVCS, подразумеваемой Robotlegs, и создать отдельный класс обслуживания, который управляет всем этим, и просто запустить процесс из команды, вместо того, чтобы пытаться передавать контроль между вашими командами и службами. В качестве дополнительного преимущества вы можете заменить экземпляры реального сервиса на тестовые сервисы, когда вам не нужно подключаться к фактическим данным (например, для выполнения проектных работ).