Zmienne (VarStore)
Źródło:
VarStore.js
OrbitoViewEngine udostępnia centralny magazyn zmiennych — VarStore — z którego korzystasz projektując widok. Zmienne pozwalają przekazywać stan między widokami, zapamiętywać ustawienia strony oraz dzielić dane globalnie pomiędzy stronami.
Każda zmiana zmiennej emituje zdarzenie na EventBus, dzięki czemu widoki mogą reagować reaktywnie (np. przez onVarChange, renderIf lub odczyt w szablonach Handlebars).
Trzy poziomy zmiennych
Projektując widok masz dostęp do 3 poziomów (zakresów) zmiennych. Różnią się one czasem życia oraz zasięgiem współdzielenia:
| Poziom | Zakres / czas życia | Persystencja | Notacja w widoku |
|---|---|---|---|
| view | Dane pojedynczego widoku. Znikają po zniszczeniu widoku (np. zmiana strony) | brak (pamięć) | <viewId> / <viewId>.<pole> |
| page | Zmienne całej strony, zapamiętywane dla ID strony (zwykle jej URL) | localStorage (ove_page_<pageId>) | $page.<klucz> |
| global | Zmienne globalne, współdzielone między wszystkimi stronami | localStorage (ove_global_<klucz>) | $global.<klucz> |
1. Zmienne widoku (view)
Najwęższy zakres. Każdy widok przechowuje swoje dane pod własnym viewId (np. wartość inputu, zaznaczenie w select). Dane żyją tak długo jak widok — znikają, gdy widok zostaje usunięty z DOM (np. przy zmianie strony) i nie są zapisywane w localStorage.
Do danych innego widoku odwołujesz się przez jego viewId (z opcjonalną dot-notation do konkretnego pola):
type: text
content: "Wybrano: {{ select001.value }}"
W warunkach (condition, renderIf) oraz przy zbieraniu danych do akcji (withData) używasz tej samej notacji:
type: button
label: Zapisz
renderIf:
select001.value:
$in:
- active
- pending
Uwaga: Zmiana danych widoku emituje
viewVar:changedorazviewVar:changed:<viewId>. Nasłuchuj jej przezonVarChangezescope: view.
W tym samym zakresie trzymasz stan UI — tryb edycji, rozwinięty panel, zaznaczony wiersz. Zapisujesz go akcją setVar ze scope: view pod dowolnym kluczem (nie kolidującym z id widoku), a odczytujesz tak samo jak dane widoku — bez prefiksu:
onClick:
action: setVar
scope: view
key: editingCustomer
value: true
type: card
renderIf:
editingCustomer: true
Taki stan celowo nie trafia do localStorage — po przeładowaniu strony formularz nie zostaje w trybie edycji.
2. Zmienne strony (page)
Zmienne przypisane do bieżącej strony (identyfikowanej zwykle przez jej URL). Są zapamiętywane w localStorage pod kluczem ove_page_<pageId>, więc przetrwają przeładowanie strony, ale są odseparowane między różnymi stronami.
Ustawiasz je akcją setVar ze scope: page, a odczytujesz w szablonach i warunkach przez prefiks $page:
type: button
label: Pokaż zamówienia
onClick:
action: setVar
scope: page
key: activeTab
value: orders
type: text
content: "Aktywna zakładka: {{ $page.activeTab }}"
Zmiana emituje pageVar:changed oraz pageVar:changed:<klucz> — reaguj na nią przez onVarChange ze scope: page:
type: card
onVarChange:
- scope: page
key: activeTab
action:
action: reload
target: contentTable
3. Zmienne globalne (global)
Najszerszy zakres — zmienne współdzielone pomiędzy wszystkimi stronami aplikacji. Zapamiętywane w localStorage pod kluczem ove_global_<klucz>. Idealne do ustawień użytkownika, roli, motywu itp.
Ustawiasz je akcją setVar ze scope: global, a odczytujesz przez prefiks $global:
type: button
label: Tryb ciemny
onClick:
action: setVar
scope: global
key: theme
value: dark
type: card
title: Panel administracyjny
renderIf:
$global.role: admin
content: []
Zmiana emituje globalVar:changed oraz globalVar:changed:<klucz> — reaguj na nią przez onVarChange ze scope: global.
Kolekcje w stanie i „cichy” zapis
W zmiennej można trzymać całą kolekcję — pozycje dokumentu, listę załączników — i edytować ją bez round-tripu do API akcjami arrayPush / arrayRemove / arraySet. Działają we wszystkich trzech zakresach i zawsze zapisują kopię, nigdy nie mutują poprzedniej tablicy w miejscu.
Każdy zakres ma dwa rodzaje zapisu:
| Zapis | Zdarzenia | Kto reaguje |
|---|---|---|
zwykły (setVar, arrayPush, arrayRemove) | <zakres>Var:changed + <zakres>Var:changed:<klucz> | wszystkie widoki i warunki |
cichy (arraySet bez rerender) | <zakres>Var:itemChanged + <zakres>Var:itemChanged:<klucz> z { key, index, field, value } | wyłącznie widoki text |
Cichy zapis istnieje po to, żeby edycja jednej pozycji nie przebudowywała listy — przebudowa niszczy input, w którym użytkownik właśnie pisze.
Reaktywny text
Widok text sam subskrybuje zmienne użyte w content — nie trzeba dla niego pisać onVarChange ani wołać reload:
type: text
content: 'Razem: {{ money (sum docItems "netValue") }}'
Reaguje przy tym na oba rodzaje zapisu (również na cichy), bo render tekstu jest tani i nie niszczy żadnej kontrolki. Pętli sprzężenia zwrotnego nie ma: text niczego do VarStore nie zapisuje.
Odwołania do zmiennych w szablonach
Wszystkie trzy poziomy są dostępne jednocześnie w szablonach Handlebars oraz w polach widoków. Silnik buduje wspólny obiekt danych:
| Notacja | Źródło |
|---|---|
{{ $page.<klucz> }} | zmienne bieżącej strony (VarStore.getAllPageVars()) |
{{ $global.<klucz> }} | zmienne globalne (VarStore.getAllGlobalVars()) |
{{ <viewId>.<pole> }} | dane innego widoku (VarStore.getAllViewsData()) |
type: text
content: "Witaj {{ $global.userName }}, jesteś na zakładce {{ $page.activeTab }}"
Tej samej notacji używasz w polu withData akcji callMethod, aby przekazać wartości zmiennych do metody API:
action: callMethod
module: core/orders
method: update
withData:
- statusInput001
- "$page.activeTab"
- "$global.role"
Podsumowanie: wybierz najwęższy poziom, który wystarcza — view dla stanu chwilowego, page dla stanu jednej strony, global dla danych współdzielonych w całej aplikacji.
Powiązane: Akcje (ActionHandler) · BaseView – onVarChange / renderIf
