Modely

Java Enterprise Edition Wicket Tipy a triky 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.

Model

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().

AbstractReadOn­lyModel

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).

Model vracející 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.

Model vracející 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>
PropertyModel

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).

ResourceModel čeština
ResourceModel angličtina

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 &lt;-&gt; en</a>

StringResourceModel

Předcházející model ResourceModel byl zjednodušením modelu StringResource­Model. 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.

StringResourceModel čeština
StringResourceModel angličtina

Jiný způsob použití StringResource­Model. 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>
StringResourceModel další

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.".

LoadableDetacha­bleModel

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 LoadableDetacha­bleModel.

.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.randomUU­ID().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í

LoadableDetachableModel první načtení

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

LoadableDetachableModel další načtení

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

LoadableDetachableModel 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".

Vlastní model
Vlastní model po kliknutí

Příloha obsahuje zdrojové kódy.


 

Stáhnout

Staženo 0x (2.02 kB)
Aplikace je včetně zdrojových kódů v jazyce Java

 

  Aktivity (1)

Článek pro vás napsal vita
Avatar
vita

Jak se ti líbí článek?
Ještě nikdo nehodnotil, buď první!


 


Miniatura
Všechny články v sekci
Tipy a triky pro Wicket

 

 

Komentáře

Děláme co je v našich silách, aby byly zdejší diskuze co nejkvalitnější. Proto do nich také mohou přispívat pouze registrovaní členové. Pro zapojení do diskuze se přihlas. Pokud ještě nemáš účet, zaregistruj se, je to zdarma.

Zatím nikdo nevložil komentář - buď první!