5

私はGWTを初めて使用し、複合ウィジェットを継承しようとしているページを作成しようとしていますが、複合ウィジェットの値は動的です。

私のメインページは次のようなものです。

         .....
         .....
         <g:Button>Open composite widget</g:button>
         .....
         .....

これは、次のような別のポップアップパネルを開いています。

         .....
         <table>
            <tr><td>Top: <myCompany:userMeasurementUnit/> </td></tr>
            <tr><td>Bottom: <myCompany:userMeasurementUnit/> </td></tr>
            <tr><td>Left: <myCompany:userMeasurementUnit/> </td></tr>
            <tr><td>Right: <myCompany:userMeasurementUnit/> </td></tr>
        </table>

上記は私たちを示す必要があります

         top (cm)
         bottom (cm)
         left (cm)
         right (cm)

しかし、メインページからカスタムウィジェット、つまりusermeasurementunitに値を渡す方法がわかりません。

          <myCompany:userMeasurementUnit/>

私のusermeasurementunitは次のようなものです。

UIBinder:

     <htmlpanel tag="span" ui:field="unit"/>

コンポジットウィジェットは

      usermeasurementunit extends Composite {

       public usermeasurementunit(){
           initwidget...
       }

       public onload() { 
         ...
       }

       }

ここで、ボタンをクリックすると、cm、インチ、またはメートルの測定単位を渡します。イベントバスを使用して試しましたが、ボタンをクリックするとポップアップパネルが画面に表示されず、イベントがキャッチされないため、役に立ちませんでした。誰かがこれに関して私を助けてくれるなら、私は本当にこのことに苦労しているので、私は本当に感謝するでしょう。

敬具

4

2 に答える 2

13

まず、GWTでのオブジェクトのインスタンス化フローを理解する必要があります。

彼らはそれを「動的バインディング」ではなく「遅延バインディング」と呼んでいます。

Uibinderxmlファイルはレイアウトテンプレートです。そして、その背後にあるJAvaソースBeanは、一般的なプログラミング用語では「コードビハインド」として知られています。

uibinderレイアウトテンプレートの役割または目的は、レイアウトをオフロードすることです(インターネット上では、英語を話さない多くのプログラマーが「レイアウト」を記述します。これは、構文的には面白いですが、同じことです)。コードビハインドは、レイアウトの応答の制御に焦点を当てることができます。

それはMVPの態度に似ています。プレゼンテーション制御から分離されたビューの実装。これらのフィールドが配置されている位置を正確に知らなくても、コードビハインドエラーなしで記述できます。コードビハインドに集中するために、UI要素が適切にレイアウトされていないテンプレートを単純に提供することもできます。おそらくその後。1つのuibinderテンプレートはモバイル用で、もう1つはデスクトップ用ですが、同じコードビハインドを共有できます。

uibinderテンプレートによって表示される表示値は、uibind中に一度だけ決定されます。コードビハインドで宣言されたオブジェクト/変数の絶えず変化する値へのuibinderフィールドの動的バインディングはありません。

uibindの後にuibinderフィールドの値を動的に変更/伝播するには、コードビハインドでその値を意図的に設定するか、その変更を検出するリスナーを作成する必要があります。

public class Graceland {

  @UiField
  Label pressure;

  @UiField
  Button reset;

  public void setPressure(int value) {
    pressure.setText(value);
  }

  @UiHandler("reset")
  void nameDoesNotMatter(ClickEvent ev) {
    pressure.setText(default);
  }
}

GWT.create()は、コンパイル時にテンプレートのJavaソースを生成します。GWT.createはランタイム関数ではありません。

@UiFieldと@UiHandlerは、uibind中にテンプレートのuifieldにバインドされます。

uibind()の役割は、ほとんどの場合実行時ではなく、コンパイル時でもあります。そのファイナリティは実行時に実現されますが、オブジェクトを構築するためのすべてのjavascriptコードとそれぞれの値は、コンパイル時に生成され、実行時のuibind中に1回だけ実行されます。

したがって、コードビハインドの動的な役割を完全に置き換えることはできませんが、単にレイアウトのタスクから解放して、プログラマーがコードビハインドのクリーンな部分を汚すことができるようにすることを目的としています。レイアウトのスパゲッティソースでは可能な限り少なくします。

ただし、バインド時にuibinderフィールドの値に「動的に」影響を与えたい場合は、それUi:withが友だちです。

package z.mambazo;
public class Graceland {
  ....
  String initialPressure(){
    /* "dynamically" obtain the pressure from the
     * pressure gauge in the petroleum distillation stack
     * during uibind
     */
  }
}

Graceland.ui.xml:

<ui:UiBinder blah...blah>
  <ui:with type="z.mambazo" field="zulu"/>
  <g:VerticalPanel>
    <g:Label
      ui:field="pressure"
      text="the temperature is :{zulu.initialPressure}"/>
  </g:VerticalPanel>
</ui:UiBinder>

ui:with beanは、テンプレートのコードビハインドである必要はありません。ui:with Beanに引数なしのコンストラクターがあるか、コンストラクターの引数に対応する属性を持つui:withタグを指定する必要があります。

ui:withを使用するには、タグテキストではなくvalue属性でinit値を宣言する必要があることに注意する必要があります。

<g:Label
  ui:field="pressure"
  text="the temperature is : {zulu.initialPressure}"/>

いいえ

<g:Label ui:field="pressure">
  the temperature is : {zulu.initialPressure}
</g:Label>

2番目の方法は、テキストをそのまま複製することです。

ただし、次のようにすることもできます。

<g:HtmlPanel>
  the temperature is :&nbsp;
  <g:Label ui:field="pressure"
    text="{zulu.initialPressure}"/>
</g:HtmlPanel>

また、すべてのGWT UI Javaコードは、暫定的に生成されたものも含めて、すべてブラウザーのJavascriptに変換されることに注意してください。したがって、ui:withで参照するクラスはすべて、JavaバイトコードではなくJavaソースコードである必要があります。そして、それらのソースコードは、呼び出しチェーンの呼び出しバイトコードをいつでもダウンしてはなりません。

于 2012-07-15T08:13:21.183 に答える
1

必要なのは共有リソースです。次に例を示します。

MeasurementConstants.java:

package com.acme.client;

public class MeasurementConstants {

    private final String measurementUnit;

    public MeasurementConstants(String measurementUnit) {
        this.measurementUnit = measurementUnit;
    }

    public String measurementUnit() {
        return measurementUnit;
    }

}

UiBinderMeasurement.java:

package com.acme.client;

import com.google.gwt.core.client.GWT;
import com.google.gwt.uibinder.client.UiBinder;
import com.google.gwt.uibinder.client.UiFactory;
import com.google.gwt.user.client.ui.Composite;
import com.google.gwt.user.client.ui.Widget;

public class UiBinderMeasurement extends Composite {

    private static UiBinderI18nUiBinder uiBinder = GWT
            .create(UiBinderI18nUiBinder.class);
    private MeasurementConstants constants;

    interface UiBinderI18nUiBinder extends UiBinder<Widget, UiBinderMeasurement> {
    }

    public UiBinderMeasurement(MeasurementConstants constants) {
        this.constants = constants;
        initWidget(uiBinder.createAndBindUi(this));
    }

    @UiFactory
    public MeasurementConstants getConstants() {
        return constants;
    }

}

UiBinderMeasurement.ui.xml:

<!DOCTYPE ui:UiBinder SYSTEM "http://dl.google.com/gwt/DTD/xhtml.ent">
<ui:UiBinder xmlns:ui="urn:ui:com.google.gwt.uibinder"
    xmlns:g="urn:import:com.google.gwt.user.client.ui">

    <ui:with type="com.acme.client.MeasurementConstants" field="constants"></ui:with>

    <g:HTMLPanel>
        <table>
            <tr><td><g:Label text="Top ({constants.measurementUnit}):" /> </td></tr>
            <tr><td><g:Label text="Bottom ({constants.measurementUnit}):" /> </td></tr>
            <tr><td><g:Label text="Left ({constants.measurementUnit}):" /> </td></tr>
            <tr><td><g:Label text="Right ({constants.measurementUnit}):" /> </td></tr>
        </table>
    </g:HTMLPanel>
</ui:UiBinder>

これで、次のように呼び出すことができます。

new UiBinderMeasurement(new MeasurementConstants("cm"))
于 2012-07-15T08:36:52.413 に答える