Вызов getString() в конструкторе в Wicket дает ошибку

У меня проблемы с локализацией в калитки.

Это код:

private String displayString;
private TextField<string> myTextField;

public myPage(DomainObject domainObject){
 if(domainObject != null)
 displayString = domainObject.getDisplayString();
 myTextField = new TextField<string>("myTextField", new PropertyModel<string>(this, "displayString"));

 if(Strings.isEmpty(displayString))
 displayString = getString("mandatory"); //<- error message here

}
</string></string></string>

Проблема заключается в том, что вызов getString в конструкторе приводит к сообщению об ошибке ("... Иногда это может привести к недопустимому или отсутствию локализованного ресурса..."). Я хочу использовать PropertyModel для TextField, так как я не хочу переводить строку, которую я получаю из domainObject.getDisplayString(). Я не хочу, чтобы изменения, внесенные в TextField, напрямую влияли на значение в domainObject. Можно избавиться от сообщения об ошибке, сделав это вместо getString:

if(Strings.isEmpty(displayString))
 displayString = new ResourceModel("mandatory").getObject(); //<- no error message

Насколько я понимаю, это то же самое, что и вызов getString (вы просто снимаете предупреждения, но проблема все еще существует). Решением, о котором я думал, является следующее:

@Override
protected void onAfterRender() {
 super.onAfterRender();
 if(Strings.isEmpty(displayString))
 displayString = getString("mandatory"); //<- no error message
}

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

2 ответа

Вызов getString() требует, чтобы компонент находился внутри иерархии компонентов, где он мог получить к нему доступ родительский, чтобы иметь возможность вернуться к свойствам, определенным там или далее в дереве. Это невозможно в конструкторе компонента (поскольку вы добавляете его к нему parent в более поздней точке). Wicket 1.5 вводит функцию onInitialize для этих операций. С версиями Wicket до этого есть простой способ подражать этому поведению:

В вашем базовом компоненте и странице задайте пустой пустой метод, как

protected void onInitialize() {}

и добавьте это в метод onBeforeRender:

protected void onBeforeRender() {
...
 if (!hasBeenRendered()) {
 onInitialize();
 }
...
}

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


Как насчет многоразового поведения:

public class MandatoryBehavior extends AbstractBehavior {
 public void onComponentTag(Component component, ComponentTag tag) {
 if (((AbstractTextComponent)component).isRequired() && Strings.isEmpty(tag.get("value"))) {
 tag.put("value", component.getString("mandatory"));
 }
 }
}

Однако вам придется проверять представленные значения в валидаторе.

Заполнители HTML5 еще приятнее.

licensed under cc by-sa 3.0 with attribution.