6

場所の変更時にアクティビティの状態を更新するベスト プラクティスは何ですか? カテゴリのリストとカテゴリ内のアイテムのリストを表示するビューを持つアクティビティがあるとします。別のカテゴリが選択されている場合、アプリはカテゴリ ID を持つ新しい場所に移動します。次に、アイテムを更新するだけで、カテゴリ リストを再読み込みする新しいアクティビティを作成したくありません。

私の現在のアプローチは次のようなものです:

public class AppActivityMapper implements ActivityMapper {

    private ItemListActivity itemListActivity;

    ...

    public Activity getActivity(final Place place) {
        final Activity activity;

        if (place instanceof ItemListPlace) {
            if (itemListActivity == null) {
                itemListActivity = new ItemListActivity((ItemListPlace) place, clientFactory);
            } else {
                itemListActivity.refresh((ItemListPlace) place);
            }
            activity = itemListActivity;
        } else {
            itemListActivity = null;
        }

        ...
        return activity;
    }

    ...
4

3 に答える 3

5

代替手段は次のとおりです。

  • アクティビティ内からをリッスンしPlaceChangeEventます (その後、 内のアクティビティのキャッシュFilteredActivityMapperとを使用して、要求されたときにのみ新しいアクティビティを作成するように削減できます)。†</p>CachingActivityMapperActivityMapper

  • コンポーネントに をリッスンさせてビジネス指向のイベントに変換PlaceChangeEventさせると、アクティビティは ではなくそれらのイベントをリッスンします。それ以外は上記と同じです。PlaceChangeEvent

  • アクティビティを「画面」から分離し、「画面」をメソッドでシングルトンにし、reset()そのメソッドをアクティビティから呼び出しますstart(この場合、カテゴリ ID を引数として渡す可能性があります)。シングルトンである「画面」は、カテゴリリストを一度だけロードするようにすることができます。

  • あなたの場合、単にカテゴリ リストを共有キャッシュに入れることもできます。これにより、新しいアクティビティを作成してアクティビティを再利用する必要がなくなります。カテゴリ リストは一度取得され、キャッシュに入れられます。その後のアクティビティインスタンスはキャッシュにあるものだけを使用します。これは上記と似ていますが、より単純であり、アプリケーションの他の部分でキャッシュを使用できます。

ただし、個人的にはあなたのアプローチを採用したいと思います(小さな例外を除いて、以下を参照)。それは最も単純/最も簡単だからです。「画面」からアクティビティを分離することもオプションです。GWT チームは、Expenses サンプルでこのアプローチの調査を開始しました (MVP を使用してアクティビティの責任をプレゼンターの責任から分離する) が、残念ながら完了することはありませんでした。

それ以外には、今のところベストプラクティスが実際に出現しているとは思いません。


†。私は自分のアクティビティを使用されている場所と結合するのが好きではありません (呼び出しの結合もあまり好きではgoToありませんが、クリーンでシンプルな代替手段をまだ見つけていません)。このオプションで; 同様に、あなたのように場所をアクティビティ コンストラクターとrefreshメソッドに渡すのではなく、その場所から情報を抽出してアクティビティに渡します (たとえば、あなたの場合、アクティビティにカテゴリ ID のみを指定し、インスタンスではなく、すべての場合にItemListPlace単純に呼び出しsetCategory、カテゴリ ID をコンストラクターに渡すことさえしません)。

于 2012-08-22T13:44:49.410 に答える
3

私の意見では、

  • の役割は、からActivityMapperを返すことです。ActivityPlace
  • の役割は、与えられたバックを からActivityManager開始し、現在のものと異なる場合は停止することです。あなたの場合、現在のを「更新/更新」したいと思います。ActivityActivityMapperActivity

したがって、特定のタイプのActivityMapperの同じインスタンスが常に返されるように、を変更します。これを行う良い方法は、GIN を使用し、シングルトン スコープを使用して.ActivityPlace...in(Singleton.class)Activity

これを行うと、URL を変更するときに場所が同じままである場合 (つまり、URL の # の後と : の前に同じ単語があることを意味します)、場所のタイプが同じままになると、ActivityMapperは同じインスタンスを返しますActivityそのため、ActivityManagerは に対して何もしませんActivity。のl.126をチェックActivityManager

if (currentActivity.equals(nextActivity)) {
  return;
}

私には2つのオプションがあります。最初のものは、トーマスが言ったようにPlaceChangeEvent、あなたの で聞くことActivityです。あなたが受け取る新しいPlaceものは、与えられた新しいURLに基​​づいて内部に新しいパラメータを持つことができ、あなたのActivity.

2 つ目は、Activity/Place パターンに沿ったもので、によって返されたが現在の と同じである場合にActivityManagerで update(Place) メソッドを呼び出すように を変更することです。ActivityActivityActivityMapperActivity

これらの解決策はまだ試していませんが、すぐに試してみます...その時点でその投稿を更新できるかもしれません。

詳細については、このトピックについてブログに書いたこの記事を参照してください。

パターンを理解するのに役立つように作成した小さなスキーマを次に示します。

ここに画像の説明を入力

于 2013-02-27T10:11:04.350 に答える
1

新しいアクティビティを作成するか、以前のアクティビティ (または null) を与えることによって、アクティビティを返す以外に、ActiviyMapper でロジックを実行しません。私によると、マッパーは refresh() やアクティビティが何をするかについて知る必要はありません。

その場合、'refresh()' のロジックは、トークンを保持する場所を介してアクティビティに与えられます。そのトークンは、リクエストの状態 (新しいページ、リロード、ID など) に関する情報を保持している必要があります。

アクティビティでは、最初に、このアクティビティに関連する View を要求し (ヒント:「ClientFactory」によって指定されるシングルトンを使用することをお勧めします)、次にそのビューのプレゼンターを作成し、それらをバインドします。

最後に、アクティビティはプレースからのトークンを使用して、状態に関する情報をプレゼンターに提供します。次に、ページにビューを追加します。

デフォルトでは、場所とアクティビティを使用して、同じ場所に移動しても何も実行されない (リロードなし) ことを知っておくとよいでしょう。しかし、token と activity-mapper で簡単に処理できます。

あなたのケースに適した解決策が見つかることを願っています。幸運を。

于 2012-08-23T20:25:07.423 に答える