Flex: служба LCDS возвращает ноль Asynctoken при выполнении во второй раз - PullRequest
0 голосов
/ 23 декабря 2011

Я занимаюсь разработкой приложения Flex с использованием RobotLegs, LiveCycle DS и Java.Я пытаюсь реализовать функцию обновления, используя LCDS, но у меня странное поведение:

Это код ActionScript в команде execute RobotLegs, используемый для обновления:

 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 все работает нормально.AsyncToken приятно возвращается функцией 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 ]

1 голос
/ 31 января 2012

aysnctoken возвращает ноль, если у вас нет изменений для фиксации. Надеюсь, это поможет.

0 голосов
/ 03 января 2012

WWW, Это не совсем ответ как таковой, но мне нужно больше места, чем даст мне комментарий. Однако я не вижу, как весь ваш код связан достаточно хорошо, чтобы дать вам хороший ответ.

В общем, сигнатуры результата и ошибки должны , а не выглядеть так, как вы описываете как «правильную» подпись. AsyncToken ожидает IResponder, чей ментод ошибки и результата имеет параметр single , который является объектом. Как правило, это вызывается при событии сбоя или результата (в зависимости от ситуации).

Теперь я собираюсь на территорию, которая для меня чисто теоретическая. Мне кажется, что класс DataService может создать только один AsyncToken, так как соединение остается открытым. Если это так, возможно, ошибочная сигнатура метода повредит AsyncToken до такой степени, что он не может быть возвращен для использования методом. В коде, который вы вставили, я не увидел ничего похожего на то, что он вызывает ваши методы результата и ошибки по-своему.

Я сильно сомневаюсь, что проблема в коде Java. AFAIK, AsyncToken создается и настраивается для вызова функций в ответчике еще до того, как будет выполнен вызов (по крайней мере, так он работает с HTTPService или amf). Я ожидаю, что есть некоторая ошибка, которая «услужливо» подавляется, так что вы могли бы выиграть от пошагового выполнения кода.

Я бы посоветовал вам немного отступить назад и немного сложнее взглянуть на «S» часть архитектуры MVCS, подразумеваемой Robotlegs, и создать отдельный класс обслуживания, который управляет всем этим, и просто начать процесс с Команда, вместо того, чтобы пытаться передать контроль между командами и службами. В качестве дополнительного преимущества вы можете заменить экземпляры реального сервиса на тестовые сервисы, когда вам не нужно подключаться к фактическим данным (например, для выполнения проектных работ).

...