2014-08-30 77 views
0

我在頁面上使用調色板組件,並且我希望其中兩個中的可用元素根據第一個中選擇的內容進行更改。掛毯:來自調色板組件的事件

達到此目的的最佳方法是什麼?哪些事件由調色板組件引發,我可以聽,調整調色板的模型並執行區域更新?我認爲這是可行的the same way as for select components做這樣的事情:

void onValueChanged() { 
    // do something 
} 

不幸的是,它不適合調色板工作。

我正在使用Tapestry 5.4-beta-6,但是我猜測自從早期版本以來,事情並沒有改變那麼多。

+1

只是幾個筆記; 5.4-beta-17現在可用(作爲預覽,即將投票),但我不能誠實地說自beta-6以來發生了什麼變化。這裏的客戶端有很多強大的功能,Palette組件產生willChange和didChange事件(包括對監聽者的否決權)。 – 2014-09-02 19:02:26

+0

謝謝,我不知道。聽起來很有希望。我會看看。 – martin 2014-09-03 09:05:46

+0

我怎樣才能抓住這些事件?我嘗試了以下,但沒有一個被調用:@OnEvent(value =「willChange」,component =「myPalette」),@OnEvent(value =「t5:palette:willChange」,component =「myPalette」)。我錯過了什麼嗎? – martin 2014-09-08 09:52:19

回答

0

我終於將didChange元素與類似的混合元素一起使用,如Observe mixin。我對Github進行了演示,感興趣的任何人。

就在幾個注意事項:

  • 我用5.4測試版6,它已經具備了必要的客戶端事件。
  • 我無法使用Tapestry JavaScript模塊工作,所以我仍然使用javascriptSupport.addInitializerCall。
  • 剩下的問題是,使用區域更新更新第二個調色板將重置用戶在此調色板中所做的任何更改,因爲它們只保留在客戶端(在隱藏字段中)。我仍然需要研究這一點,但這不是原始問題的一部分。
+0

您的索引頁正在初始化他們的聲明中的變量,您絕對不應該這樣做(例如'private List availableSubCategories = new ArrayList ()')。這會導致變量從一個請求流到另一個請求。使用渲染事件來初始化(例如setupRender()或onPrepare())。 – 2014-09-23 16:14:05

0

我可能會用mixin做到這一點。

public class PaletteChange { 
    @Parameter 
    private String zone; 

    @InjectContainer 
    private Palette palette; 

    public void afterRender() { 
     Link eventLink = componentResources.createEventLink("change"); 
     JSONObject args = new JSONOBject(
      "id", pallete.getClientId(), 
      "url", eventLink, 
      "zone", zone 
    ); 
     javascriptSupport.addScript("palleteChange(%s)", args); 
    } 

    Object onChange(@RequestParameter("value") String value) { 
     CaptureResultCallback<Object> callback = new CaptureResultCallback<Object>(); 
     resources.triggerEvent("change", new String[] { value }, callback); 
     return callback.getResult(); 
    } 
} 

的Javascript

function palleteChange(spec) { 
    var field = $('#' + spec.id + '/select[1]'); 
    field.on('change', function() { 
     var zoneManager = Tapestry.findZoneManagerForZone(spec.zone); 
     var params = { value: field.val() }; 
     zoneManager.updateFromURL(spec.url, params); 
    }); 
} 

然後用混入在你的代碼

<t:palette t:id="myPalette" t:mixins="paletteChange" zone="myZone" ... /> 
<t:zone t:id="myZone"> 
    ... 
</t:zone> 

@Inject 
private Zone myZone; 

Block onChangeFromMyPalette(String value) { 
    doStuff(value); 
    return myZone.getBody(); 
} 

一個類似的mixin見here

+0

看起來很有希望。我會盡快嘗試。謝謝! – martin 2014-09-02 14:48:20

+0

更改事件不是正確的。然而,當使用t5:palette:didChange代替時,該方法可以工作。 – martin 2014-09-23 15:11:30