Гобелен: события из палитры

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

Каков наилучший способ достичь этого? Какие события генерируются компонентом палитры, которые я мог бы прослушать, адаптировать модель палитры и выполнить обновление зоны? Я думал, что это будет работать так же, как для отдельных компонентов, которые делают что-то вроде этого:

void onValueChanged() {
    // do something
}

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

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

2 ответа

Решение

Я наконец использовал didChange элемент вместе с похожим миксином, как миксин Observe. Я выложил демо на Github для всех, кому интересно.

Всего несколько заметок:

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

Я бы, наверное, сделал это с миксином.

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.

Другие вопросы по тегам