Modely
Model je rozhraní, které umožňuje komponentě modifikovat (měnit) data
bez toho, aby znala, jak jsou tato data získávána. Modelem ve Wicketu je
jakákoliv implementace rozhraní org.apache.wicket.model.IModel
.
Každá komponenta může mít model. Komponenta, které je model přiřazen má
několik metod pro nastavení a získání modelu a také metody, které se
volají při změně modelu.
Modely
Podíváme se nejdříve na nejjednodušší komponentu a tou je Label (popisek).
.java
Label label = new Label("label", "Label"); add(label);
Vytvoření komponenty Label a její přidání.
.html
<div wicket:id="label"></div>
Umístění komponenty do html stránky.

Zápis
Label label = new Label("label", "Label"); add(label);
je identický se zápisem
Label label = new Label("label", Model.of("Label")); add(label);
Vytvoří se komponenta Label, jejíž model obsahuje řetězec "Label"
(metoda getObject()
vrací řetězec "Label"). Máme sice
komponentu s modelem, ale data, která model poskytuje se nemění. Vytvoříme
si tedy jinou komponentu, u které se bude objekt vracený modelem měnit. Je
možné si udělat vlastní implementaci rozhraní IModel, ale pro běžné
použití má Wicket již připraveno množství hotových modelů.
Model
Tuto základní implementaci rozhraní IModel již známe.
Model.of("Label");
Vytvoří model, jehož getObject() metoda vždy vrátí řetězec "Label". Identický zápis je
new Model("Label");
Pokud to shrnu, model Model zabalí objekt, který dostane v konstruktoru.
Tento objekt je pak vracen metodou getObject()
.
AbstractReadOnlyModel
Toto je model, který nabízí data pouze pro čtení. Musí se
naimplementovat pouze metoda getObject()
;
.java
IModel<String> timeModel = new AbstractReadOnlyModel<String>() { @Override public String getObject() { return new Date().toString(); } }; Label timeLabel = new Label("timeLabel", timeModel); add(timeLabel);
.html
<div wicket:id="timeLabel"></div>
Vytvoří label, která vrací pokaždé aktuální čas (pokud budete obnovovat stránku, po každém načtení se zobrazí aktuální čas).

IModel<Integer> randomModel = new AbstractReadOnlyModel<Integer>() { private Random gen = new Random(); @Override public Integer getObject() { return gen.nextInt(); } }; Label randomLabel = new Label("randomLabel", randomModel); add(randomLabel);
.html
<div wicket:id="randomLabel"></div>
Vytvoří label, která zobrazuje náhodné číslo.

PropertyModel
Přistupuje k proměnné objektu.
public class Person implements Serializable { private String name; private String surname; public String getName() { return name; } public void setName(String name) { this.name = name; } public String getSurname() { return surname; } public void setSurname(String surname) { this.surname = surname; } }
.java
Person person = new Person(); person.setName("František"); person.setSurname("Koudelka"); IModel<String> namePropertyModel = new PropertyModel<String>(person, "name"); Label namePropertyLabel = new Label("namePropertyLabel", namePropertyModel); add(namePropertyLabel);
.html
<div wicket:id="namePropertyLabel"></div>
To samé vytvoříme pro surname
a tři řádky kódu
směstnáme do jednoho.
.java
add(new Label("surnamePropertyLabel", new PropertyModel<String>(person, "surname")));
.html
<div wicket:id="surnamePropertyLabel"></div>

ResourceModel
Tento model vrací lokalizovaný řetězec.
Properties s českými texty …_cs.properties
label.text=Text popisku
Properties (defaultní) s anglickými texty ….properties
label.text=Text of the label
.java
IModel<String> resourceModel = new ResourceModel("label.text"); Label resourceLabel = new Label("resourceLabel", resourceModel); add(resourceLabel);
.html
<div wicket:id="resourceLabel"></div>
Pokud bude mít uživatel v prohlížeči nastavenu českou lokalizaci, text popisku bude v češtině. Pokud bude mít jinou lokalizaci, text bude v angličtině (těch lokalizací může být samozřejmě mnohem více).


Zde je ještě kód pro vytvoření odkazu pro přepínání
locale
.
.java
Link localeLink = new Link("localeLink") { @Override public void onClick() { Locale locale = Session.get().getLocale(); if (locale.equals(Locale.ENGLISH)) { Session.get().setLocale(new Locale("cs")); } else { Session.get().setLocale(Locale.ENGLISH); } } }; add(localeLink);
.html
<hr> <a href="#" wicket:id="localeLink">cs <-> en</a>
StringResourceModel
Předcházející model ResourceModel byl zjednodušením modelu StringResourceModel. Tento model nabízí mnohem větší možnosti.
…_cs.properties
label.longtext=Jeho jméno bylo {0} a příjmení {1}.
….properties
label.longtext=His name was {0} and surname {1}.
.java
IModel<String> stringResourceModel = new StringResourceModel("label.longtext", this, null, new Object[]{"Petr", "Novák"}); Label stringResourceLabel = new Label("stringResourceLabel", stringResourceModel); add(stringResourceLabel);
.html
<div wicket:id="stringResourceLabel"></div>
Při českém locale zobrazí text: "Jeho jméno bylo Petr a příjmení Novák.", při jiném locale: "His name was Petr and surname Novák." atd.


Jiný způsob použití StringResourceModel. Zde použijeme objekt person použitý v jednom z předchozích příkladů.
…_cs.properties
label.otherlongtext=Jeho jméno bylo ${name} a příjmení ${surname}.
….properties
label.otherlongtext=His name was ${name} and surname ${surname}.
.java
IModel<String> stringResourceModelOther = new StringResourceModel("label.otherlongtext", this, new Model<Person>(person)); add(new Label("stringResourceLabelOther", stringResourceModelOther));
.html
<div wicket:id="stringResourceLabelOther"></div>

Objekt person má tyto hodnoty proměnných: name = "František", surname = "Koudelka". Při českém locale zobrazí text: "Jeho jméno bylo František a příjmení Koudelka.", při jiném locale: "His name was František and surname Koudelka.".
LoadableDetachableModel
U tohoto modelu je třeba implementovat jedinou metodu load(), která nahraje a vrátí dočasný modelový objekt. Pokud jste zkoušeli aktualizovat stránku a pak se vrátit například pomocí tlačítka zpět, nebo jste mezi stránkami přecházeli a následně se zpět vraceli, určitě jste zaznamenali, že vše bylo tak jak má. Stránky, na které jste se pomocí tlačítka zpět vrátili byly takové, jaké by jste očekávali (stejné). Wicket toho dosahuje tak, že celou stránku uloží (serializuje). Pokud se k ní vracíte, deserializuje ji zpět a zobrazí. Může se ale stát, že data poskytvaná modelem a zobrazená na stránce jsou velmi objemná a nebo se mění, takže tlačítko zpět by zobrazilo již neaktuální data. Toto je možné řešit pomocí metody detach() modelu a nebo použít například LoadableDetachableModel.
.java
IModel<String> detachableModel = new LoadableDetachableModel<String>() { @Override protected String load() { return UUID.randomUUID().toString(); } }; add(new Label("detachableModelLabel", detachableModel));
.html
<div wicket:id="detachableModelLabel"></div>
Metoda UUID.randomUUID().toString() generuje náhodný řetězec. Všimněte si, že pokud použíjete tlačítko zpět, nezobrazí se původní řetězec, ale řetězec zcela nový - provede nové načtění modelového objektu.
První načtení

Po kliknutí na odkaz pro změnu locale (načte se znovu stránka).

Po kliknutí na tlačítko zpět.

Vytvoření vlastního modelu
Vlastní model vytvoříme tak, že vytvoříme třídu, která bude implementovat rozhraní IModel. V příkladu použijeme anonymní třídu. Zároveň přidáme odkaz, který po kliknutí změní hodnotu modelového objektu. Metoda getObject() bude vracet retěžec v upper case (velká písmena). Metodu detach() zatím nevyužijeme.
.java
final IModel<String> myModel = new IModel<String>() { private String str = "default text"; @Override public void detach() {} @Override public String getObject() { return str.toUpperCase(); } @Override public void setObject(String object) { this.str = object; } }; add(new Label("myLabel", myModel));
Odkaz pro změnu textu.
add(new Link("textLink") { @Override public void onClick() { myModel.setObject("changed text"); } });
.html
<div wicket:id="myLabel"></div> <a href="#" wicket:id="textLink">link</a>
Při načtení stránky se zobrazí text "DEFAULT TEXT" a po kliknutí na link "CHANGED TEXT".


Příloha obsahuje zdrojové kódy.
Stáhnout
Stažením následujícího souboru souhlasíš s licenčními podmínkami
Staženo 4x (2.02 kB)
Aplikace je včetně zdrojových kódů v jazyce Java