2010-07-26 2 views
2

HI guys, Я хотел добавить событие AJAX на свою домашнюю страницу, но это не сработает! Я понял, что если я удалю функцию onComponentTag, она работает хорошо. Я понятия не имею, почему это случилось, может быть, вы можете мне помочь! Thats мой код:Wicket AJAX + OnComponentTag

final TextField<String> searchInput = new TextField<String>("searchInput", model) { 

    @Override 
    protected void onComponentTag(final ComponentTag tag) { 
    super.onComponentTag(tag); 
    tag.put("id", this.getId()); 
    if (params.getString("search") != null) { 
     tag.put("value", params.getString("search")); 
    } 
    } 
    }; 

    searchInput.add(new AjaxFormComponentUpdatingBehavior("onfocus") { 
    @Override 
    protected void onUpdate(final AjaxRequestTarget target) { 
    System.out.print("never saw that message :("); 
    searchInput.setDefaultModelObject(""); 
    target.addComponent(searchInput); 
    } 

    }); 

Thx много за помощь! CU

ответ

5

Во-первых, вам не нужно переопределять onComponentTag() вообще. В качестве состояния seanizer, если ваш действительно необходимо указать идентификатор разметки самостоятельно, используйте setMarkupId (id). Вы должны понять, почему Wicket рекомендуется управлять идентификаторами компонентов.

Во-вторых, атрибут значения, который вы добавляете, не требуется - Wicket автоматически добавляет этот компонент для этого компонента. Назначенное значение - это значение объекта модели компонента. См. Источник для TextField.onComponentTag().

В-третьих, в качестве состояний seanizer компоненты, которые должны быть обновлены с помощью ajax, должны выводить свои идентификаторы разметки - реализация ajax в Wicket использует идентификатор в качестве селектора для элемента. Кроме того, все поведение Wicket ajax, которые расширяют AbstractDefaultAjaxBehavior, автоматически устанавливают outputMarkupId (true) на компонент, к которому они привязаны (см. Источник AbstractDefaultAjaxBehavior.onBind()). Это включает AjaxFormComponentUpdatingBehavior.

Итак:

String id = "searchInput"; 
final TextField<String> searchInput = new TextField<String>(id, model); 
searchInput.setMarkupId(id); 

searchInput.add(new AjaxFormComponentUpdatingBehavior("onfocus") { 
    @Override 
    protected void onUpdate(final AjaxRequestTarget target) { 
    System.out.print("never saw that message :("); 
    searchInput.setDefaultModelObject(""); 
    target.setOutputMarkupId(true); 
    target.addComponent(searchInput); 
    } 
}); 

Наконец, я бы вопрос, что вы на самом деле пытаетесь достичь с этим поведением. Я не вижу причин, чтобы обойти это событие на сервере. Наверняка какая-то клиентская JS более уместна?

+0

вы забыли setOutputMarkupId (true) :-) –

+0

См. источник AbstractDefaultAjaxBehavior.onBind() - поведение устанавливает для вас флаг (извините, это было неясно - Я отредактировал свой ответ, чтобы сделать его более ясным). – ireddick

5
tag.put("id", this.getId()); 

не способ сделать это в калитку.

вместо этого, используйте

component.setOutputMarkupId(true) 

(либо в вашем компоненте конструктора или в безвыходном вашего поведения (в) метод), чтобы калитка написать идентификатор, и если вы абсолютно необходимо контролировать то, что идентификатор (который почти никогда не бывает), вы можете сделать

component.setMarkupId("myId") 

также, вы, вероятно, не следует назначать значение тега самостоятельно, использовать модель (модель обработки чрезвычайно умный в калитку, прочтите more about models). Для onComponentTag допустимы действия, но они намного превосходят то, что вы делаете. Пусть калитка делает то, что делает калитка, и все будет хорошо.


EDIT: ОК, еще некоторые разъяснения

посмотреть на the source code of AjaxFormComponentUpdatingBehavior, особенно ту часть, где сгенерирован Javascript обработчик событий.

protected final CharSequence getEventHandler() 
{ 
    return generateCallbackScript(
        new AppendingStringBuffer("wicketAjaxPost('") 
        .append(getCallbackUrl(false)).append(
     "', wicketSerialize(Wicket.$('" 
         + getComponent().getMarkupId() + "'))")); 
} 

Как вы можете видеть, калитка использует getMarkupId() для определения фактического идентификатора. Идентификатор, который вы задали с помощью tag.put (id), полностью неизвестен калитке, и поэтому поведение не может работать.

Ставка ¥ особые пометки Для покупок необходима авторизация Стандартная вещь, чтобы сделать - установленOutputMarkupId (true). Это единственный правильный способ показать калитки для отображения id (кроме setOutputMarkupPlaceholder (true), который внутренне вызывает прежний метод). Таким образом, вы убедитесь, что запись калитки id - это идентификатор калитки. Если это не отображает идентификатор, вы, вероятно, нарушаете поведение по умолчанию, перезаписывая onComponentTag.

Посмотрите the source code of Component, особенно на onComponentTag(), метод переопределении:

protected void onComponentTag(final ComponentTag tag) { 
    // if(setOutputMarkupId(true) was set) 
    if (getFlag(FLAG_OUTPUT_MARKUP_ID)) { 

     // set id attribute 
     tag.put(MARKUP_ID_ATTR_NAME, getMarkupId()); 
    } 
} 

[Комментарии мои. Кстати, это источник древней версии, но я не нашел ни одного источника в Интернете, и функциональность не изменилась.]

Теперь, если, как и в вашем случае, вы хотите установить идентификатор компонента вручную, вы должны использовать

component.setMarkupId("myId") 

и конечно

setOutputMarkupId(true) 

, а также. Если это не сработает, перейдите на сайт JIRA с калитки и сообщите об ошибке. Но я сомневаюсь, что это стандартная функциональность, которая работает для тысяч пользователей.

+0

извините, но я не могу следовать за вами. 1) Я попробовал setOutputMarkupId (правда), но он не распечатывает мой идентификатор! Мне нужен ID для моего CSS! 2) Я никогда не хотел менять идентификатор и никогда не буду :) 3) это не решает мой вопрос :( Может быть, я просто недостаточно умный :) Пожалуйста, помогите! – Sylvus

+0

см. Мой обновленный ответ. вам нужно использовать как setMarkupId (myId), так и setOutputMarkupId (true) –

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