AjaxSliderのバグ

WicketとjQueryの連携にwiQueryを使ってスライダーを使いたい。

AjaxSliderクラスを継承。スライダーのつまみを掴んだ瞬間、startイベントでサーバサイドにイベントを通知して、アトはslideイベントにバインドして、つまみを掴んでいる間は、jQueryで処理というクラスを作ってみた。

使用したバージョンはwiQuery1.5.0 wicketは1.5.2

ちなみに、wiQueryではsetter系メソッドでいろいろと処理が動いているので
getter系メソッドでオーバーライドとかしないようにしている。

public class HogeSlider extends AjaxSlider {

  public HogeSlider(String id, Number min, Number max) {
    super(id, min, max);
  }

  @Override
  protected void onInitialize() {
    super.onInitialize();

    // スライド中のイベント
    setSlideEvent(new JsScopeUiEvent() {

      @Override
      protected void execute(JsScopeContext scopeContext) {
        // あとからsetAjaxStartEvent()を登録すると無効になる。
        scopeContext.append("console.log('slide now');");
      }
    });

    // スライド開始時にAjax通信する
    setAjaxStartEvent(new ISliderAjaxEvent() {

      @Override
      public void onEvent(AjaxRequestTarget target, AjaxSlider slider, int value, int[] values) {
        System.out.println("ajax start event!!");
      }
    });
  }
}

が、イベントが思うように動作しない。

しょっちゅうサーバサイドと通信が走るし、console.logには何も出力されなくなりsetSlideEvent()の処理が動かない。ようするに使えない。

setAjaxStartEvent()をコメントアウトすると、正常に’slide now’という文字が出力される。
悪さをしているのはsetAjaxStartEvent()で間違いない。

AjaxSliderクラスを確認する。

  public void setAjaxStartEvent(ISliderAjaxEvent ajaxStartEvent)
  {
    this.ajaxEvents.put(SliderAjaxEvent.ajaxStartEvent, ajaxStartEvent);
    setSlideEvent(new SliderAjaxJsScopeUiEvent(this, SliderAjaxEvent.ajaxStartEvent));
  }

はい、ビンゴ!

slideイベントに登録されてる。本来ならstartイベントであるはずだ。

ついでに、AjaxSliderクラスの親クラスであるSliderクラスのsetSlideEvent()も調査。

  public Slider setSlideEvent(JsScopeUiEvent slide)
  {
    this.options.put("slide", slide);
    return this;
  }

this.options.put()しているのはただのMapなのでイベントは上書きされて、最初にsetSlideEvent()で登録したイベントは無効になる。これで現象は全部つかめた。

イベントの上書きは、とりあえず妥協してもいいだろう。しかし、バインドするイベントは間違えては困る。スコープの関係でAjaxSliderクラスそのものを修正しなければならない。

  public void setAjaxStartEvent(ISliderAjaxEvent ajaxStartEvent)
  {
    this.ajaxEvents.put(SliderAjaxEvent.ajaxStartEvent, ajaxStartEvent);
    //setSlideEvent(new SliderAjaxJsScopeUiEvent(this, SliderAjaxEvent.ajaxStartEvent));
    setStartEvent(new SliderAjaxJsScopeUiEvent(this, SliderAjaxEvent.ajaxStartEvent));
  }

として再コンパイルすれば期待通りの動作となる。

コメントをどうぞ。

TrackBack URI :