1

GWT 2.4.0 を使用して、遅延バインディング ルールを使用して uibinder テンプレートを別のテンプレートに置き換えようとしています。

これを行うために私が思いついた方法は、uibinder のインスタンスを返す各 uibinder テンプレートの具象クラスを作成することです。ここに例があります。

public class ThemeOneUiBinderImpl {

    @UiTemplate("ThemeOne.ui.xml")
        interface ThemeOneUiBinder extends UiBinder<Widget, PageToTheme> {
    }

    private static ThemeOneUiBinder uiBinder = GWT.create(ThemeOneUiBinder.class);

    public static UiBinder<Widget, PageToTheme> getImpl() {
        return uiBinder;
    }
}

次に、基本的に同じ ThemeTwoUiBinderImpl という 2 番目のクラスがあります。私のクラスは ThemeOneUiBinderImpl を参照し、getImpl().createAndBindUi(this) を呼び出します

そして、次の遅延バインディング ルール

<replace-with class="package.ThemeTwoUiBinderImpl">
    <when-type-is class="package.ThemeOneUiBinderImpl"/>
    <when-property-is name="theme" value="theme2"/>
</replace-with>

これらのルールを設定すると、コンパイルすると、順列の数が 2 倍になり、何かが実行されていることがわかります...しかし、ページを読み込むと、theme1 uibinder がまだ読み込まれています。2 つの問題があります。

  1. なぜ機能しないのですか?
  2. 順列の数が 2 倍になるのはなぜですか? プロパティを theme2 に設定すると、theme2 の順列のみがコンパイルされると思いましたが、両方に対してコンパイルされますか?
  3. 遅延バインディングをどのように使用するように設計されていますか? 私がやっていることと似た外観パターンを使用して評価しましたが、私がする必要があることは完全にやり過ぎのようで、すでに2つのカスタムuibindersを書いています。これらのコンポーネントは、再利用または拡張できません。テーマは、単純なカスタム ヘッダー用です。

考え?ソリューション?ありがとう!

4

3 に答える 3

3

クラスのテンプレートを置き換えることができるGoogleの意図された方法をお話ししましょう。

uibinded javaクラスのuiテンプレートを置き換えるには、クラスを拡張するだけです。これは、ビューとしてのテンプレートとモデルとしてのコードに対するMVPの姿勢からある程度生まれています。幾分。アイデアは、モデルを変更せずにモデルのビューをいつでも置き換えることができるということですが、モデルへの追加を禁止することもありません。

私がしているのは、デフォルト/ダミーのテンプレートを使用して基本クラスを作成することです。

拡張クラスが基本クラスと同じパッケージにない場合、基本クラスのuibinedフィールド/リソース/メソッドはパブリックである必要があります。

実際、私が通常行うことは、基本クラスではなく拡張クラスにGWT.createを持っていることです。

  • ベースを抽象化することができます(抽象クラ​​スで実行するとGWT.createが鳴ります)。
  • テンプレートを作成する必要はまったくありません。クラスは@uifield、@ uihandler、@ uichild、blah blahなどのuibinderアノテーションで満たされていますが、クラスにはテンプレートxmlがありません。

次に、基本クラスを拡張して、uiテンプレートを使用してuibinderクラスを作成します。ここで、uiテンプレートのフィールド/リソースは、基本クラスのuifield /リソースに加えて、拡張クラスに追加したフィールド/リソースと完全に一致します。

この背後にある原則は次のとおりです。

基本uibindedクラスの完成した拡張には、相互uiテンプレートが必要です。この場合、基本クラスに独自のuiテンプレートがあるかどうかに関係なく、テンプレートは基本クラスのuiフィールド/リソースを完全に再実装する必要があります。

「完了」とは、その拡張クラスのテンプレートでGWT.createメソッドが呼び出されることを意味します。

このルールの結果は、テンプレートを再実装せずにuibinedクラスを拡張できないことです。

uibinderを使用して適切にレイアウトされたダイアログボックスがあるとします。また、外観を変更せずに、微調整のために拡張することもできます。残念ながら、拡張ダイアログボックスでは、UI /レイアウトを変更する予定がない場合でも、基本クラスのテンプレートファイルのコピーを作成する必要があります。

便利な方法がすでにある場合は、gwt.xmlでテンプレート置換throreplace-withを実行する必要はないと思います。

あなたがしていることは難解であり、私はそれを分析することに時間を費やすとは思わない。

于 2012-08-22T04:42:12.653 に答える
0

GWT の外観デザイン パターンをもう一度見直したところ、replace-with がどのように機能しているかがよくわかっていませんでした。クラスの具体的な実装を別の実装に置き換えていると思いました。しかし、よく見ると、GWT.create を使用して作成された抽象クラスまたはインターフェースが必要であることがわかりました。リフレクションで同じことをするのと同じように、外観を理解し、考えることは、それを理解するのに本当に役立ちました。

また... Blessed Geekが指摘したように、抽象ベースがある場合、クラスが適切に置き換えられていない場合、GWT.createは失敗します。

私は今、私の見解で次のことを持っています

public interface MyHeaderAppearance {
    UiBinder<Widget, MyHeaderView> getUiBinder();
    public int getHeight();
}

private final LoginPageAppearance appearance;

public MyHeaderView() {
    appearance = GWT.<MyHeaderAppearance> create(MyHeaderAppearance.class);
}

public void render() {
    panel.add(appearance.getUiBinder().createAndBindUi(this))
}

私のテーマの実装は、MyHeaderAppearanceImpl というクラスに MyHeaderAppearance インターフェイスを実装するだけです。複数のテーマをサポートするために、各テーマのパッケージと、各テーマ パッケージに MyHeaderAppearanceImpl のインスタンスがあります。

次に、テーマの実装コードを次のように置き換えています

ThemeOne.gwt.xml
<module>
    <replace-with  class="theme1.MyHeaderAppearanceImpl">
        <when-type-is class="MyHeaderAppearance"/>
    </replace-with>
</module>

このようなテーマをメインモジュールに含めます

<inherits name="theme.ThemeOne" />

それは機能していて満足していますが、改善のアイデアはありますか?

于 2012-08-22T22:24:47.223 に答える