我是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() {
         ...
       }

       }

现在,我想在单击按钮时以厘米,英寸或米为单位通过任何度量单位。我使用事件总线进行了尝试,但是它没有帮助,因为当我单击按钮popuppanel时,它不在屏幕上,并且无法捕获事件。如果你们中的任何一个可以帮助我,我将非常感激,因为我确实在努力解决这一问题。

亲切的问候

最佳答案

首先,您需要了解GWT中的对象实例化流程。

他们称其为“延迟绑定(bind)”,而不是“动态绑定(bind)”。

Uibinder xml文件是布局模板。而且其背后的JAva源bean在一般编程术语中称为“代码隐藏”。

uibinder布局模板的作用或目的是减轻版​​面设计的负担(在互联网上,许多非英语语言的程序员编写“版面设计”,尽管在语法上很有趣,但它们是同一回事),以便后面的代码可能专注于控制布局的响应。

这类似于MVP的态度。查看实现与表示控件分离。您甚至可以不知道这些字段的确切位置就可以编写无代码隐藏的错误。您甚至可以简单地提供一个模板,其中ui元素的布局不正确,以便首先专注于代码隐藏。也许之后。一个用于移动设备的uibinder模板,另一个用于桌面设备的uibinder模板-但它们可以共享相同的后台代码。

在uibind中一次确定所有受uibinder模板影响的显示值。 uibinder字段没有动态绑定(bind)到在后面的代码中声明的对象/变量的不断变化的值。

要在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不是运行时函数。

在uibind期间,@UiField和@UiHandler绑定(bind)到模板中的uifield。

uibind()的作用主要不是运行时,而是编译时。虽然,它的确定性是在运行时实现的,但是所有javascript代码和用于构造对象的各个值都是在编译时生成的,并且在运行时uibind期间仅执行一次。

因此,其目的不是要完全取代后台代码的动态作用,而仅仅是将其从布局任务中解放出来,以便我们程序员可以将干净的后台代码弄脏为布局的意大利面条来源尽可能少。

但是,如果您希望在绑定(bind)期间“动态”影响uibinder字段的值,则Ui:with是您的 friend 。
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>

第二种方法是简单地按原样复制文本。

但是,您也可以这样进行:
<g:HtmlPanel>
  the temperature is :&nbsp;
  <g:Label ui:field="pressure"
    text="{zulu.initialPressure}"/>
</g:HtmlPanel>

另外,请注意,所有GWT UI Java代码,即使是临时生成的代码,都都转换为浏览器Javascript。因此,无论您使用ui:with引用什么类,都必须使用Java源代码而不是Java字节码。并且这些源代码在任何时候都不得向下调用链调用字节代码。

10-04 23:21