2012-07-14 62 views
4

我是GWT的新手,試圖製作一個試圖繼承複合小部件的頁面,但複合小部件的值是動態的。gwt中的uibinder的動態值

我的主頁是服用點,如:

  ..... 
     ..... 
     <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不在屏幕上,並沒有捕捉事件。如果你們中的任何一個人能夠幫助我,我會非常感謝,因爲我真的在爲這件事而苦苦掙扎。

親切的問候

回答

11

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

他們稱之爲「延遲綁定」,而不是「動態綁定」。

Uibinder xml文件是一個佈局模板。而且它背後的JAva源代碼在一般編程術語中稱爲「代碼隱藏」。

uibinder佈局模板的作用或目的是爲了減輕網絡佈局()在互聯網上許多非英語的程序員寫的「佈局」,雖然語法上有趣,但它是相同的東西),以便代碼隱藏可以專注於控制佈局的響應。

類似於MVP的態度。查看與呈現控件分離的實現。您可以自由編寫代碼隱藏錯誤,而無需準確瞭解這些字段佈局的位置。你甚至可以簡單地提供一個模板,其中的UI元素沒有正確佈局,以便專注於你的代碼隱藏。也許在那之後。一個用於移動的uibinder模板,另一個用於桌面 - 但他們可以共享相同的代碼隱藏。

由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期間執行一次且僅執行一次。

因此,其目的不是要完全替代代碼隱藏的動態角色,而是簡單地將其從佈局任務中解放出來,這樣我們程序員就可以擁有一塊乾淨的代碼 - 在儘可能少地使用佈局的意大利麪條源污染。

但是,如果您希望在綁定期間「動態」影響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:豆不必是模板的代碼隱藏。無論是ui:with bean都有一個無參構造函數,或者你必須提供ui:帶有與構造函數參數相對應的屬性的標籤。

您必須注意,爲了使用ui:with,必須在值屬性中聲明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引用哪一類:必須使用Java源代碼而不使用Java字節碼。而且這些源代碼在任何時候都不能停止調用鏈式調用字節碼。

+0

似乎你已經在你的UI冷落的類名:有型。 – 2014-08-03 11:38:13

+0

你說得對。我錯過了包括它。 – 2014-08-03 17:34:44

1

你需要的是shared resources。下面是一個例子:

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"))