2014-08-30 2 views
0

Я использую компоненты палитры на странице, и я хочу, чтобы доступные элементы в двух из них менялись в зависимости от того, что выбрано в первом.Гобелен: События из компонента Palette

Каков наилучший способ достичь этого? Какие события выбрасываются компонентом палитры, которые я мог бы прослушать, адаптировать модель палитры и выполнить обновление зоны? Я думал, что это будет работать the same way as for select components делать что-то вроде этого:

void onValueChanged() { 
    // do something 
} 

К сожалению, это не работает для палитр.

Я использую Tapestry 5.4-beta-6, но я думаю, что с ранних версий это не так сильно изменилось.

+1

Всего несколько нот; 5.4-бета-17 теперь доступен (как предварительный просмотр, идет голосование), и я не могу честно сказать, что там изменилось с бета-6. Здесь много энергии на стороне клиента, с компонентом Palette, создающим команды willChange и didChange (включая право вето для слушателя). –

+0

Спасибо, я этого не знал. Звучит очень многообещающе. Я это проверю. – martin

+0

Как я могу поймать это событие? Я попробовал следующее, но никто из них не вызвал: @OnEvent (value = "willChange", component = "myPalette"), @OnEvent (значение = "t5: palette: willChange", component = "myPalette"). Я что-то упускаю? – martin

ответ

0

Я, наконец, использовал элемент didChange вместе с аналогичным микшином, подобным Observe mixin. Я поставил демо на Github для всех, кто заинтересован.

Всего несколько нот:

  • Я использовал 5.4 бета 6, у него уже есть необходимые на стороне клиента события.
  • Я не мог заставить его работать с помощью модуля JavaScript Tapestry, поэтому я все еще использую javascriptSupport.addInitializerCall.
  • Оставшаяся проблема заключается в том, что обновление второй палитры с обновлением зоны приведет к сбросу всех изменений, внесенных пользователем в эту палитру, поскольку они хранятся только на стороне клиента (в скрытом поле). Мне все равно нужно будет изучить это, но это не часть первоначального вопроса.
+0

Ваша страница индекса инициализирует переменные в их объявлении, которые никогда не должны делать (например, 'private List availableSubCategories = new ArrayList ()'). Это вызовет переключение переменных из одного запроса в другой.Вместо инициализации используйте событие рендеринга (например, setupRender() или onPrepare()). –

0

Я бы, наверное, сделал это с помощью микширования.

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> 

Page

@Inject 
private Zone myZone; 

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

См here для подобного Mixin.

+0

Это выглядит многообещающе. Я попробую это как можно скорее. Благодаря! – martin

+0

Событие изменения не является правильным. Однако подход работает при использовании t5: palette: didChange вместо этого. – martin

Смежные вопросы