Dane powiązania i opcje konfiguracyjne

Widok może być powiązany z powiązaniem danych i opcjami konfiguracyjnymi. Dostęp do tych danych jest możliwy dzięki kontekstowi widoku. Aby uzyskać dostęp do danych powiązania i opcji konfiguracyjnych, należy użyć funkcji get i set języka JavaScript. Nie można w tym celu używać notacji JavaScript z kropkami.

context.binding

Obiekt powiązania, jeśli jest zdefiniowany, udostępnia dane powiązane z widokiem. Dla każdego widoku może być zdefiniowane maksymalnie jedno powiązanie danych.

Dostęp do danych powiązanych z widokiem można uzyskać przy użyciu konstrukcji: this.context.binding.get("value"), gdzie value jest specjalną nazwą właściwości zwracającą powiązanie danych. Jeśli na przykład widok jest powiązany z obiektem local.phoneBook.title, może on uzyskać tytuł książki telefonicznej w następujący sposób:


if (!! this.context.binding){
var title = this.context.binding.get("value")
}
Główną przyczyną, dla której widoki są powiązane z danymi, jest możliwość powiadomienia widoku, jeśli powiązane dane zostały zmodyfikowane. Środowisko widoku wykrywa zmiany danych w powiązanym obiekcie i automatycznie powiadamia widok, wywołując jego funkcję procedury obsługi zdarzeń change. Należy zauważyć, że te powiadomienia będą wysyłane do widoku tylko w sytuacji, jeśli zmianie ulegnie sam obiekt powiązania, ale nie w sytuacji, kiedy ulegną zmianie jakiekolwiek jego właściwości lub właściwości podrzędne. W poniższych sekcjach omówiono poszczególne typy danych oraz przedstawiono schematy spraw, w których do otrzymywania powiadomień o zmianie danych wymagany jest dodatkowy kod.

Wiązanie z prostymi i złożonymi typami danych

W przypadku prostych typów danych, takich jak łańcuchy i liczby, środowisko widoku wykrywa zmiany danych i automatycznie powiadamia o nich widok. Jeśli na przykład widok jest powiązany z prostym typem łańcucha local.phoneBook.title, w przypadku zdarzenia zmiany określającego, że tytuł uległ zmianie i ma nową wartość, wywoływana jest funkcja change() widoku. Są o tym informowane wszystkie widoki powiązane z łańcuchem local.phoneBook.title.

W przypadku złożonych typów danych, takich jak obiekty biznesowe, widok jest powiadamiany tylko, jeśli zmianie ulegnie sam obiekt powiązania, ale nie w sytuacji, kiedy ulegną zmianie jakiekolwiek jego właściwości lub właściwości podrzędne. Na przykład można założyć, że widok jest powiązany z obiektem złożonym local.phoneBook, a nie z typem prostym takim jak typ String (łańcuch). Obiekt phoneBook ma wiele właściwości. Jedną z nich jest właściwość title. Jeśli zmianie ulegnie właściwość title, funkcja change nie jest wywoływana, ponieważ widok jest powiązany z obiektem phoneBook, a nie z właściwością title. Funkcja change jest wywoływana tylko w przypadku, kiedy zmianie ulegnie cały obiekt phoneBook. Aby widok był powiadamiany o zmianie właściwości obiektu złożonego, należy ręcznie powiązać widok z właściwością przy użyciu funkcji bind() lub bindAll(). Należy zauważyć, że funkcji bind() i bindAll() można używać w ten sam sposób dla opcji konfiguracyjnych.
Ważne: Funkcja bindAll() obsługuje tylko jeden poziom głębokości w drzewie obiektów, więc jeśli obiekt ma wiele poziomów (obiekty zagnieżdżone), widok musi wywołać bindAll() wielokrotność czasu dla każdego poziomu obiektu.
bind(path, callback, [scope])
Powiadamia widok przy użyciu wywołania zwrotnego, jeśli określona właściwość uległa zmianie. Zasięg jest opcjonalnym parametrem, który określa zasięg kontekstu wywołania zwrotnego. Funkcja zwraca uchwyt do wywołania zwrotnego.
bindAll(callback, [scope])
Powiadamia widok przy użyciu wywołania zwrotnego, jeśli zmianie uległa jakakolwiek właściwość obiektu. Zasięg jest opcjonalnym parametrem, który określa zasięg kontekstu wywołania zwrotnego. Funkcja zwraca uchwyt do wywołania zwrotnego.

W przypadku sygnatury wywołania zwrotnego należy zapoznać się z tematem function (event) .

W poniższym przykładzie przedstawiono kod, który można dodać do procedury obsługi zdarzeń ładowania dla widoku, aby ręcznie powiązać właściwości obiektu złożonego:
   var binding = this.context.binding.get("value");  //this is a complex object
   this.property2Handle = binding.bind("property1.property2", function(e) {some code}, this);
   this.property3Handle = binding.get("property3").bindAll(this.myBindAllChangeHandler, this);
   ......
   this.mybindAllChangeHandler(event) { .....};
W tym przykładzie widok jest powiązany z obiektem złożonym i ustawiane jest powiadamianie procedury obsługi zmiany, jeśli zmianie ulegnie właściwość binding.property1.property2 (która jest łańcuchem). Ustawiane jest również powiadamianie innej procedury obsługi zmiany, jeśli zmianie ulegnie jakakolwiek właściwość podrzędna właściwości property3. W obu przypadkach zasięg, w którym wywoływana jest procedura obsługi zmiany, to zasięg this widoku.

Powiązanie z typem listy

W przypadku powiązania z listą widok jest powiadamiany automatycznie w przypadku zmiany całego obiektu listy. Na potrzeby tego przykładu założono, że widok jest powiązany z listą local.phoneBook.person[]. Jeśli zostanie utworzona nowa lista osób i zostanie ona ustawiona na powiązanie widoku, na przykład przy użyciu składni skryptu serwera tw.local.phoneBook.person = new tw.object.listOf.person();, środowisko automatycznie powiadamia widok o zmianie.

Powiązanie z aktualizacjami listy

Aby otrzymywać powiadomienia o dodaniu, usunięciu lub zastąpieniu elementu, należy ręcznie powiązać widok przy użyciu funkcji bindAll(). W poniższym przykładzie kodu funkcja listUpdated widoku jest wywoływana przy każdym dodaniu elementu do listy, usunięciu elementu z listy lub zastąpieniu elementu na liście.
var binding = this.context.binding.get("value"); //this is a List object
this.bindAllHandle = binding.bindAll(this.listUpdated, this);

Powiązanie z właściwościami listy

Oprócz elementów, lista ma również właściwości specjalne, takie jak właściwość definiująca elementy listy wybierane przez użytkownika. Właściwości specjalne są opisane w poniższej tabeli.
Tabela 1. Właściwości specjalne listy
Właściwość Typ Opis
listAllSelectedIndices Tablica Indeksy elementów listy wybranych przez użytkownika. Liczba wybranych indeksów może być większa niż jeden. Przy ustawianiu właściwości listAllSelectedIndices indeksy są przekazywane w tablicy. Właściwości listAllSelectedIndices należy użyć podczas aktualizowania wyboru listy.
listAllSelected Tablica Tablica wszystkich elementów wybranych przez użytkownika. Właściwości listAllSelected należy użyć do subskrybowania zmiany tej właściwości. Ta właściwość jest tylko do odczytu.
listSelectedIndex Liczba całkowita Indeks wybranego elementu. Ta wartość odpowiada wartości elementu indeksu 0 tablicy listAllSelectedIndices. Właściwości listSelectedIndex należy użyć do subskrybowania zmiany tej właściwości. Ta właściwość jest tylko do odczytu.
listSelected Obiekt Wybrany element. Ta wartość odpowiada wartości elementu indeksu 0 tablicy listAllSelected. Właściwości listSelected należy użyć do subskrybowania zmiany tej właściwości. Ta właściwość jest tylko do odczytu.
Funkcja bindAll() nie obejmuje tych właściwości specjalnych.
Aby otrzymywać powiadomienia o zmianie właściwości specjalnej, można zasubskrybować tę pojedynczą właściwość przy użyciu funkcji bind(). Ogólnie rzecz biorąc, wystarczy subskrybować jedną właściwość specjalną (oznacza to, że nie ma konieczności subskrybowania wszystkich właściwości specjalnych). Aby wywoływać funkcję indicesChanged widoku przy każdej zmianie wartości właściwości listAllSelectedIndices, można dodać poniższy przykładowy kod do procedury obsługi zdarzeń ładowania.
var binding = this.context.binding.get("value"); //this is a list
this.selectedIndicesHandle = binding.bind("listAllSelectedIndices", this.indicesChanged, this);

Uzyskiwanie dostępu do elementów listy

Listy są kolekcjami typów prostych lub obiektów złożonych z właściwościami. Aby uzyskać dane z listy, należy użyć następującej notacji:
  • Aby uzyskać obiekt listy, należy użyć funkcji get("value"). Na przykład: list = this.context.binding.get("value")
  • Aby uzyskać indeksowany element, należy użyć funkcji get(index). Na przykład: list.get(0), aby uzyskać pierwszy element.
  • Aby uzyskać wartość właściwości, należy użyć funkcji get(property) . Na przykład: list.get("listSelected"), aby uzyskać wartość właściwości listSelected. Aby uzyskać wartości wszystkich innych właściwości, należy użyć podobnej składni.
  • Aby uzyskać tablicę reprezentującą elementy bazowe listy, należy użyć funkcji items. Na przykład: list.items. Danych zwróconych przez funkcję items nie należy modyfikować.

Operacje listy

Do modyfikowania listy i uzyskiwania informacji o liście używane są następujące funkcje API.
  • Aby dodać obiekt, należy użyć funkcji list.add(item). Na przykład: this.context.binding.get("value").add(item)
  • Aby usunąć obiekt, należy użyć funkcji list.remove(index). Przykład: this.context.binding.get("value").remove(0)
  • Aby zastąpić obiekt, należy użyć funkcji list.put(index, item). Na przykład: this.context.binding.get("value").put(0, item)
  • Aby uzyskać długość listy, należy użyć funkcji list.length().
  • Aby uzyskać indeksowany element lub właściwość listy, należy użyć funkcji list.get(index | property). Patrz sekcja Uzyskiwanie dostępu do elementów listy wcześniej.
  • Aby programowo zaktualizować wybraną właściwość listy, należy użyć funkcji list.set(property). Na przykład: this.context.binding.get("value").set("listAllSelectedIndices", [1, 2, 3]);

Czyszczenie powiązanych zasobów

Jeśli powiązanie nie jest już potrzebne, można zwolnić powiązane zasoby. Każda funkcja bind lub bindAll zwraca uchwyt, którego można użyć do oczyszczenia powiązania. Powiązane zasoby należy zwolnić w procedurze obsługi zdarzeń unload() lub za każdym razem, kiedy zmieniany jest cały obiekt powiązania. W przypadku zmiany danych powiązania widok wymaga zwolnienia powiązania ręcznego i ponownego powiązania z obiektem context.binding poprzez ponowne wywołanie funkcji bind i bindAll. W procedurze obsługi zdarzeń zmiany można na przykład dodać następujący kod:
if (event.type != "config"){
var binding = this.context.binding.get("value"); //this is a list
	// assumes that this.selectedIndicesHandle was initialized in the load function
  this.selectedIndicesHandle.unbind();
this.selectedIndicesHandle = binding.bind("listAllSelectedIndices", this.indicesChanged, this);
	// assumes that this.selectedIndicesHandle was initialized in the load function
this.bindAllHandle.unbind();
this.bindAllHandle = binding.bindAll(this.listUpdated, this);

}

Opcje konfiguracyjne

Widoki można wiązać nie tylko z danymi, ale również z opcjami konfiguracyjnymi. Widok może mieć wiele opcji konfiguracyjnych. Przykładem właściwości konfiguracji może być etykieta elementu sterującego przycisku. Wartości konfiguracji można pobrać przy użyciu obiektu this.context.options widoku. Obiekt context.options zawiera predefiniowaną właściwość metadata, a także właściwości zdefiniowane przez użytkownika, które można konfigurować dla widoku.
Tabela 2. Predefiniowane opcje konfiguracyjne widoku
Opcja Typ Opis
etykieta Łańcuch Wartość etykiety widoku, jeśli istnieje.
ujęcie Łańcuch Ustawienie widoczności widoku. Poprawne wartości to: "DEFAULT" | "EDITABLE" | "REQUIRED" | "READONLY" | "NONE" | "HIDDEN". Patrz Obiekt kontekstu widoku formatki. DEFAULT to kod równoważny Same as parent , który użytkownicy widzą na ekranie na liście Widoczność.
Ważne: Tabele mają właściwość konfiguracyjna Wyłącz opcję kliknięcia w celu edycji . Jej wartością domyślną jest false oznaczająca, że widoki zawarte w danej tabeli korzystają z ustawień widoczności tabeli. Oznacza to, że widoki w danej komórce są dostępne tylko do odczytu (READONLY) do momentu, gdy użytkownik kliknie w komórce. Widoki stają się wtedy edytowalne (EDITABLE) do czasu, gdy użytkownik kliknie w dowolnym miejscu poza komórką. Widoki stają się wtedy ponownie dostępne tylko do odczytu (READONLY). Gdy wartością opcji Wyłącz konieczność kliknięcia w celu edycji jest true, w tych widokach są używane ich własne ustawienia widoczności.
Ważne: ustawienie widoczności na wartość REQUIRED nie sprawdza, czy użytkownik wprowadził lub ustawił wartość. Konieczne jest podanie kodu wykonującego tę operację sprawdzania (np. przez zaimplementowanie usługi sprawdzania poprawności dla formatki zawierającej widok).
labelVisibility Łańcuch Ustawienie widoczności etykiety. Poprawne wartości to "SHOW" | "HIDE".
helpText Łańcuch Widok może użyć tej właściwości jako tekstu w dymku.
className Łańcuch Podane nazwy klas CSS. Zazwyczaj widok nie wymaga użycia tej właściwości, ponieważ nazwy klas CSS są wstawiane w atrybut DOM widoku.
htmlOverrides Mapa Odwzorowanie pary nazwa-wartość reprezentujące podany atrybut HTML. Te pary nazwa-wartość są wstawiane do atrybutu DOM widoku.
Dostęp do opcji konfiguracyjnych jest realizowany w ten sam sposób, jak w przypadku danych powiązania. Są one również aktualizowane w ten sam sposób. Na przykład:
  • Aby uzyskać predefiniowane opcje widoku, należy użyć funkcji this.context.options._metadata.*. Aby na przykład uzyskać opcję widoczności widoku, należy użyć funkcji this.context.options._metadata.visibility.get("value");.
  • Aby ustawić predefiniowane opcje widoku, należy użyć funkcji this.context.options._metadata.*. Aby na przykład ustawić opcję widoczności widoku, należy użyć funkcji this.context.options._metadata.visibility.set("value", newValue);
  • Aby uzyskać opcję konfiguracyjną zdefiniowaną przez użytkownika, należy użyć funkcji this.context.options.myOption.get("value");, gdzie myOption jest nazwą opcji.
  • Aby ustawić opcję konfiguracyjną zdefiniowaną przez użytkownika, należy użyć funkcji this.context.options.myOption.set("value", newValue);, gdzie myOption jest nazwą opcji.

Aby przekształcić obiekt danych powiązania do postaci szeregowej łańcucha JSON, należy wywołać funkcję toJson() na obiekcie powiązania danych. W celu pobrania podstawowego obiektu JavaScript reprezentującego powiązanie danych można wywołać funkcję toJSObject().