0

GWTでRequestFactoryを使用する際の問題に苦労しています。Userオブジェクトがあります。このオブジェクトには、ログインフィールドとパスワードフィールド、およびコレクションタイプの他のフィールドがあります。

public class User {
    private String login;
    private String password;
    private Set<Ressource> ressources;

    // Getters and setters removed for brievety
} 

このオブジェクトをdbに永続化する必要があるため、CRUDタイプの操作のように見えるため、RequestFactoryを使用しました。

コードのRequestFactory部分については、次のように試みました。

  1. UserRequestContextオブジェクトを作成して、新しいユーザーのリクエストオブジェクトを作成します。これは次のようなものになります:

    public interface MyRequestFactory extends RequestFactory {
        UserRequestContext userRequestContext();
        RessourceRequestContext ressourceRequestContext();
    }
    

    そして、ユーザーオブジェクトを作成するには、次のようなものがあります。

    public class UserAddScreen extends Composite {
        private UserProxy userProxy;
        EventBus eventBus = new SimpleEventBus();
        MyRequestFactory requestFactory = GWT.create(MyRequestFactory.class);
        ...
    
        public UserAddScreen() {
            ...
            requestFactory.initialize(eventBus);
        }
    
        public showUserAddScreen() {
            // Textbox for password and login
            // Listbox for ressources
        }
    
    }
    

私はそれをウィザードとして実装しようとしました。したがって、UserAddScreenの最初に、userProxyオブジェクトがあります。このオブジェクトフィールドは、ウィザードの各ステップで初期化されます。

  • 最初のステップは、ログインとパスワードを追加することです
  • 2番目のステップは、userProxyオブジェクトにリソースを追加することです。

この最後のステップでは、2つのリストボックスがあります。最初のリストボックスには、RessourceRequestContext.getAllRessourceから取得したDBテーブルRessourcesにあるすべてのリソースのリストが含まれています(RessourceIdをリストボックスアイテムとして表示するループがあります。値)と2番目のリストボックスから、選択したリソースを追加できます。これが最初のリストボックスです:

    final ListBox userRessourcesListBox = new ListBox(true);
    Receiver<List<RessourceProxy>> receiver = new Receiver<List<RessourceProxy>>() {

        @Override
        public void onSuccess(List<RessourceProxy> response) {
            for(RessourceProxy ressourceProxy : response) {
                ressourcesListBox.addItem(ressourceProxy.getNom() + " " + ressourceProxy.getPrenom(), String.valueOf(ressourceProxy.getId()));
            }
        }
    };
    RessourceRequestContext request = requestFactory.ressourceRequestContext();
    request.getAllRessource().fire(receiver);

ご覧のとおり、私のコードはDBから取得したプロキシをループし、リストボックス内の項目を初期化します。

コントロールボタンは次のとおりです。

final Button addButton = new Button(">");
    addButton.addClickHandler(new ClickHandler() {

        public void onClick(ClickEvent event) {
            for (int i = 0; i < ressourcesListBox.getItemCount(); i++) {
                boolean foundInUserRessources = false;
                if (ressourcesListBox.isItemSelected(i)) {
                    for (int j = 0; j < userRessourcesListBox
                            .getItemCount(); j++) {
                        if (ressourcesListBox.getValue(i).equals(
                                userRessourcesListBox.getValue(j)))
                            foundInUserRessources = true;
                    }

                    if (foundInUserRessources == false)
                        userRessourcesListBox.addItem(ressourcesListBox
                                .getItemText(i), ressourcesListBox
                                .getValue(i));
                }
            }
        }
    });

したがって、誰かが1人以上のユーザーを選択し、「>」ボタンをクリックすると、選択されたすべてのアイテムがuserRessourceListBoxという名前の2番目のリストボックスに移動します。

userRessourcesListBox.setWidth("350px");
    userRessourcesListBox.setHeight("180px");

その後、FINISHボタンがあり、2番目のリストボックス(最初のリストボックスから選択したもの)の項目をループし、RequestFactoryを使用して(再度)要求を実行して、ressourceProxyオブジェクトを取得して初期化します。 userProxyは、結果を含むコレクションをリソースします

final Button nextButton = new Button("Finish");

    nextButton.addClickHandler(new ClickHandler() {

        public void onClick(ClickEvent event) {
            RessourceRequestContext request = requestFactory.ressourceRequestContext();
            for(int i = 0; i < userRessourcesListBox.getItemCount(); i++) {
                Receiver<RessourceProxy> receiver = new Receiver<RessourceProxy>() {
                    @Override
                    public void onSuccess(RessourceProxy response) {
                        userProxy.getRessource().add(response);
                    }
                };
                request.find(Long.parseLong(userRessourcesListBox.getValue(i))).fire(receiver);
            }
              creationRequest.save(newUserProxy).fire(new Receiver<Void>() {

                @Override
                public void onSuccess(Void response) {
                    Window.alert("Saved");
                }
            });
        }

    });

最後に、(上記のコードで)UserProxyオブジェクトを(userProxyを作成した最初のリクエストコンテキストで)保存しようとしましたが、機能しません

creationRequest.save(newUserProxy).fire(...)

onSuccessメソッドで結果をループするときのようです:

userProxy.getRessource().add(response);

(RessourceProxyタイプの)応答を取得しますが、このメソッドを超えて、たとえば、ループ後にuserProxyオブジェクトを保存しようとすると、userProxyのressourceProxyコレクションにRessourceProxyオブジェクトがありません...

このようなことを経験したことがありますか?おそらく私はそれを正しく行っていません:UserRequestContextでリソースを取得する必要がありますか?newUserオブジェクトとリソースが同じリクエストコンテキストによって管理されるようにしますか?はいの場合、何かを混ぜ合わせるのは少し奇妙だと思います。つまり、ユーザー関連のリクエストコンテキストでリソース関連の操作を行うことの利点は何ですか。

どんな助けでも本当に本当に...そして私は本当に感謝していることを意味します;-)どうもありがとう

4

1 に答える 1

0

「…が凍結されました」というメッセージは、オブジェクトがedit()edであるか、別のインスタンスでサービスメソッドへの引数として渡されたことを意味しRequestContextます(同じサブタイプであるかどうかは関係ありませUserRequestContextRessourceRequestContext。 )まだfire()dされていないか、応答がサーバーからまだ返されていません(または、違反が返されました:レシーバーonViolationが呼び出されても、オブジェクトはonSuccessandとは異なり、編集可能onFailureです)。

更新:競合状態があります:リソースIDをループし、ユーザーが選択したアイテムの数と同じ数のリクエストを生成し、応答を待たずに(覚えておいてください:すべて非同期です)、ユーザープロキシを保存します。最後のリクエストを行うとすぐfire()に、ユーザープロキシは変更できなくなります(つまり、フリーズします)。

IMO、RessourceProxy最初に取得したsを保持し、保存する前にユーザープロキシで直接使用することをお勧めします(つまりfind()、「終了」フェーズでのリクエストはもうありません)。それらをIDでマップに入れfind、サーバーから再度戻すのではなく、マップから取得します。

于 2011-06-27T11:07:55.410 に答える