Ignite UI for Web Components Tree, también conocido como componente TreeView, es un control de alto rendimiento que visualiza estructuras de datos expandibles dentro de una UI en forma de árbol, lo que le permite aplicar carga bajo demanda para elementos secundarios. La Ignite UI for Web Components también proporciona funciones como expandir y contraer nodos, navegación de aplicaciones anidadas, los nodos del árbol Ignite UI for Web Components se pueden generar manualmente o desde una fuente de datos vinculada.
Para los usuarios finales, esto significa que pueden navegar fácilmente a través de diferentes páginas de aplicaciones, usar selecciones, casillas de verificación, agregar textos, íconos, imágenes y más.
El componente de árbol Ignite UI for Web Components permite a los usuarios representar datos jerárquicos en una estructura de vista de árbol, manteniendo las relaciones padre-hijo, así como definir una estructura de vista de árbol estática sin un modelo de datos correspondiente. Su objetivo principal es permitir a los usuarios finales visualizar y navegar dentro de estructuras de datos jerárquicas. El componente IgcTreeComponent también proporciona capacidades de carga bajo demanda, activación de elementos, selección múltiple y en cascada de elementos a través de casillas de verificación integradas, navegación con teclado integrado y más.
Web Components Tree Example
En este ejemplo básico de árbol Ignite UI for Web Components, puede ver cómo definir un árbol y sus elementos especificando la jerarquía de elementos.
<!DOCTYPE html><html><head><title>Basic Tree Example</title><metacharset="UTF-8" /><linkrel="shortcut icon"href="https://static.infragistics.com/xplatform/images/browsers/wc.png" ><linkrel="stylesheet"href="https://fonts.googleapis.com/icon?family=Material+Icons"><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Kanit&display=swap" /><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Titillium Web" /><linkrel="stylesheet"href="https://static.infragistics.com/xplatform/css/samples/shared.v8.css"type="text/css" /></head><body><divid="root"><divclass="container sample"><igc-tree><igc-tree-itemlabel="North America"><igc-tree-itemlabel="United States"></igc-tree-item><igc-tree-itemlabel="Canada"></igc-tree-item><igc-tree-itemlabel="Mexico"></igc-tree-item></igc-tree-item><igc-tree-itemlabel="South America"><igc-tree-itemlabel="Brazil"></igc-tree-item><igc-tree-itemlabel="Uruguay"></igc-tree-item></igc-tree-item><igc-tree-itemlabel="Europe"><igc-tree-itemlabel="United Kingdom"></igc-tree-item><igc-tree-itemlabel="Germany"></igc-tree-item><igc-tree-itemlabel="Bulgaria"></igc-tree-item></igc-tree-item></igc-tree></div></div><!-- This script is needed only for parcel and it will be excluded for webpack -->
<% if (false) { %><scriptsrc="src/index.ts"></script><% } %>
</body></html>html
/* shared styles are loaded from: *//* https://static.infragistics.com/xplatform/css/samples */css
Para obtener una introducción completa a Ignite UI for Web Components, lea el tema Introducción.
La forma más sencilla de empezar a utilizar IgcTreeComponent es la siguiente:
Declaring a tree
IgcTreeItemComponent es la representación de cada elemento que pertenece a la IgcTreeComponent. Los elementos proporcionan disabled, active, selected y expanded propiedades, que le dan la oportunidad de configurar los estados del elemento según sus requisitos. La value propiedad se puede utilizar para agregar una referencia a la entrada de datos que representa el elemento.
Los artículos se pueden declarar utilizando uno de los siguientes enfoques.
Declarar el árbol y sus elementos especificando la jerarquía de elementos e iterando a través de un conjunto de datos
Los elementos se pueden vincular a un modelo de datos para que sus estados expandidos y seleccionados también se reflejen en los datos subyacentes.
Declarar un árbol creando elementos estáticos independientes
Para representar un árbol, no es necesario que se necesite un conjunto de datos: se pueden crear elementos individuales sin un modelo de datos subyacente mediante la propiedad expuesta label o proporcionar un contenido de ranura personalizado para la IgcTreeItemComponent etiqueta.
<igc-tree><igc-tree-item><divslot="label">
I am a parent item 1
<imgsrc="hard_coded_src.webb"alt="Alt Text"></div><igc-tree-itemlabel="I am a child item 1"></igc-tree-item></igc-tree-item><igc-tree-item><divslot="label">
I am a parent item 2
<imgsrc="hard_coded_src.webb"alt="Alt Text"></div><igc-tree-itemlabel="I am a child item 1"></igc-tree-item></igc-tree-item></igc-tree>html
You can provide a custom slot content for each IgcTreeItemComponent's indentation, expansion and label area respectively using the provided indentation, indicator and label slots.
De forma predeterminada, se pueden expandir varios elementos al mismo tiempo. Para cambiar este comportamiento y permitir la expansión de una sola rama a la vez, se podría habilitar la singleBranchExpand propiedad. De esta manera, cuando se expande un elemento, se contraerán todas las demás ramas ya expandidas en el mismo nivel.
Además, proporciona IgcTreeComponent los siguientes métodos de API para las interacciones de elementos:
expand- Expande todos los elementos. Si se pasa una matriz items, expande solo los elementos especificados.
collapse- Contrae todos los elementos. Si se pasa una matriz items, contrae solo los elementos especificados.
IgcSelectComponent- Selecciona todos los elementos. Si se pasa una matriz de elementos, selecciona solo los elementos especificados. No emite selection evento.
Tree.Deselect- Anula la selección de todos los elementos. Si se pasa una matriz de elementos, anula la selección solo de los elementos especificados. No emite selection evento.
Web Components Tree Selection
Para configurar la selección de elementos en el componente Árbol de Ignite UI for Web Components, solo necesita establecer su selection propiedad. Esta propiedad acepta los tres modos siguientes: Ninguno, Múltiple y Cascada. A continuación echaremos un vistazo a cada uno de ellos con más detalle.
None
En IgcTreeComponent, la selección de elementos predeterminada está deshabilitada. Los usuarios no pueden seleccionar ni anular la selección de un elemento mediante la interacción de la interfaz de usuario, pero estas acciones aún se pueden completar mediante el método API proporcionado.
Multiple
Para habilitar la selección de varios elementos en el IgcTreeComponent simplemente establezca la selection propiedad en múltiples. Esto mostrará una casilla de verificación para cada elemento. Cada elemento tiene dos estados: seleccionado o no. Este modo admite la selección múltiple.
<igc-treeselection="multiple"></igc-tree>html
Cascade
Para habilitar la selección de elementos en cascada en IgcTreeComponent, simplemente establezca la propiedad de selección en cascada. Esto mostrará una casilla de verificación para cada elemento.
<igc-treeselection="Cascade"></igc-tree>html
En este modo, el estado de selección de un padre depende completamente del estado de selección de sus hijos. Cuando un padre tiene algunos hijos seleccionados y algunos no seleccionados, su casilla de verificación está en un estado indeterminado.
Keyboard Navigation
La navegación con el teclado en IgcTreeComponent proporciona una rica variedad de interacciones con el teclado para el usuario. Esta funcionalidad está habilitada de forma predeterminada y permite a los usuarios navegar a través de los elementos.
La navegación IgcTreeComponent cumple con los estándares de accesibilidad W3C y es fácil de usar.
Combinaciones de teclas
↓: navega al siguiente elemento visible. Marca el elemento como activo. No hace nada si está en el ÚLTIMO elemento.
Ctrl + ↓: navega al siguiente elemento visible. No hace nada si está en el ÚLTIMO elemento.
↑- navega al elemento visible anterior. Marca el elemento como activo. No hace nada si está en el PRIMER elemento.
Ctrl + ↑: navega al elemento visible anterior. No hace nada si está en el PRIMER elemento.
←: en un elemento principal expandido, lo contrae. Si el elemento está contraído o no tiene hijos, se mueve a su elemento principal. No hace nada si no hay ningún elemento principal.
→- en un elemento principal expandido, navega al primer elemento secundario del elemento. Si se encuentra en un elemento principal contraído, lo expande. No hace nada si el artículo no tiene hijos.
Inicio: navega al PRIMER elemento.
Fin: navega hasta el ÚLTIMO elemento visible.
Tabulador: navega al siguiente elemento enfocable de la página, fuera del árbol.
Mayús + Tabulador: navega al elemento enfocable anterior en la página, fuera del árbol.
Espacio: alterna la selección del elemento actual. Marca el nodo como activo.
Mayús + Espacio: alterna la selección de todos los elementos entre el activo y el espacio presionado mientras mantiene presionada la tecla Mayús si la selección está habilitada.
Enter: activa el elemento enfocado. Si el artículo tiene un enlace, abre el enlace.
*: expande el artículo y todos los artículos hermanos en el mismo nivel.
Cuando la selección está habilitada, la selección de elementos por parte del usuario final solo se permite a través de la casilla de verificación representada. Dado que ambos tipos de selección permiten selección múltiple, están disponibles las siguientes interacciones con el mouse y el teclado:
Hacer clic: cuando se realiza en la casilla de verificación del elemento, alterna la selección del elemento si la selección está habilitada. De lo contrario, enfoca el elemento.
Mayús + clic: cuando se realiza en la casilla de verificación del elemento, alterna la selección de todos los elementos entre el activo y el que se hizo clic mientras se mantiene presionada la tecla Mayús si la selección está habilitada.
Web Components Tree Load On Demand
La Ignite UI for Web Components se puede representar de tal manera que requiera recuperar la cantidad mínima de datos del servidor para que el usuario pueda verlos lo más rápido posible. Con este enfoque de carga dinámica de datos, solo después de que el usuario expanda un elemento, se recuperarán los elementos secundarios de ese elemento principal en particular. Este mecanismo, también conocido como Carga bajo demanda, se puede configurar fácilmente para funcionar con cualquier dato remoto.
EXAMPLE
DataService.ts
LoadOnDemandData.ts
SvgIcons.ts
TS
HTML
index.css
TreeLoadOnDemand.css
import { IgcTreeItemComponent } from"igniteui-webcomponents";
import { REMOTE_DATA, SelectableItemData } from"./LoadOnDemandData";
exportclassDataService{
/**
* As we are simulating remote data operations,
* this set is used to store the selection state of the records before reloading.
*/private _selected: Set<string> = newSet<string>();
public getChildren(parent: SelectableItemData): Promise<SelectableItemData[]> {
returnnewPromise((resolve) => {
setTimeout(() => {
const passed = REMOTE_DATA.map((item) => {
const selectionState: Partial<SelectableItemData> = {};
// If the record persists in the set it is marked as selectedif (this._selected.has(item.Name)) {
selectionState.Selected = true;
} else {
selectionState.Selected = parent.Selected;
}
returnObject.assign({}, item, selectionState);
});
return resolve(passed);
}, 2000);
});
}
publicsetSelected(item: IgcTreeItemComponent) {
const name = item.value.Name;
if (item.value.Selected) {
this._selected.add(name);
} else {
this._selected.delete(name);
}
}
}
ts
import { defineComponents, IgcTreeComponent, IgcTreeItemComponent, registerIconFromText } from"igniteui-webcomponents";
import"igniteui-webcomponents/themes/light/bootstrap.css";
import { DataService } from"./DataService";
import { DATA, ItemData, SelectableItemData } from"./LoadOnDemandData";
import { ICONS } from"./SvgIcons";
import"./TreeLoadOnDemand.css";
defineComponents(IgcTreeComponent);
exportclassTreeLoadOnDemand{
public data = DATA;
private tree: IgcTreeComponent;
private dataService = new DataService();
constructor() {
this.createIcons();
this.tree = (document.getElementById("tree") asany) as IgcTreeComponent;
this.renderItems(this.data);
this.tree.items[0].expanded = true;
this.tree.addEventListener("igcItemExpanded", this.handleExpanded.bind(this));
this.tree.addEventListener("igcSelection", this.handleSelection.bind(this));
}
privatehandleSelection(ev: CustomEvent) {
const selectionSet = newSet<IgcTreeItemComponent>(ev.detail.newSelection);
this.tree.items.forEach((item: IgcTreeItemComponent) => {
if (selectionSet.has(item)) {
item.value.Selected = true;
} else {
item.value.Selected = false;
}
// As the data is not stored on a real server, save the item selection state in the data servicethis.dataService.setSelected(item);
});
}
privateasynchandleExpanded(ev: CustomEvent) {
const item = ev.detail as IgcTreeItemComponent;
// The parent record of remote items initially has an empty Files arrayif (this.isRemoteItemsParent(item.value.Files)) {
awaitthis.loadRemoteItems(item);
this.appendRefreshIcon(item);
}
}
privateasyncloadRemoteItems(item: IgcTreeItemComponent) {
// Save current selection stateconst selecitonState = item.selected;
// Removing child items one by one modifies their parent selection stateArray.from(item.children)
.filter((c) => c.tagName === "IGC-TREE-ITEM")
.forEach((c) => item!.removeChild(c));
// Restoring selection state of the parent as before
item.selected = selecitonState;
item.loading = true;
item.disabled = true;
awaitthis.dataService.getChildren(item.value).then((data) => {
this.renderItems(data, item);
item.value.Files = data;
});
item.loading = false;
item.disabled = false;
}
privaterenderItems(items: SelectableItemData[], parent: HTMLElement = this.tree) {
if (items === undefined) {
return;
}
if (this.isRemoteItemsParent(items)) {
this.createTreeItem({Name: 'Loading', Icon: 'network'}, parent);
}
items.forEach((i) => {
const item = this.createTreeItem(i, parent);
this.renderItems(i.Files!, item);
});
}
private createTreeItem(itemData: SelectableItemData, parent: HTMLElement): IgcTreeItemComponent {
const item = document.createElement("igc-tree-item") as IgcTreeItemComponent;
item.value = itemData;
item.selected = !!itemData.Selected;
const itemSlot = this.createLabelSlot(itemData);
item.appendChild(itemSlot);
parent.appendChild(item);
return item;
}
private createLabelSlot(data: ItemData): HTMLElement {
const icon = document.createElement("igc-icon");
icon.setAttribute("name", data.Icon);
icon.setAttribute("collection", "material");
icon.classList.add("tree-item-icon");
const span = document.createElement("span");
span.innerText = data.Name;
span.classList.add("item-title");
const div = document.createElement("div");
div.setAttribute("slot", "label");
div.classList.add("item");
div.appendChild(icon);
div.appendChild(span);
return div;
}
privateappendRefreshIcon(item: IgcTreeItemComponent) {
const label = item.querySelector('div[slot="label"]');
if (!label) {
return;
}
const refreshIcon = document.createElement("igc-icon");
refreshIcon.setAttribute("name", "refresh");
refreshIcon.setAttribute("collection", "material");
refreshIcon.classList.add("tree-item-icon");
label.appendChild(refreshIcon);
refreshIcon.addEventListener("click", this.loadRemoteItems.bind(this, item));
}
privateisRemoteItemsParent(items: SelectableItemData[]){
// Parent records of remote items initially have no child items, i.e. their Files array is emptyreturnArray.isArray(items) && !items.length;
}
privatecreateIcons() {
ICONS.forEach((icon) => {
registerIconFromText(icon.name, icon.value, "material");
});
}
}
new TreeLoadOnDemand();
ts
<!DOCTYPE html><html><head><title>Load On Demand Tree Example</title><metacharset="UTF-8" /><linkrel="shortcut icon"href="https://static.infragistics.com/xplatform/images/browsers/wc.png" ><linkrel="stylesheet"href="https://fonts.googleapis.com/icon?family=Material+Icons"><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Kanit&display=swap" /><linkrel="stylesheet"href="https://fonts.googleapis.com/css?family=Titillium Web" /><linkrel="stylesheet"href="https://static.infragistics.com/xplatform/css/samples/shared.v8.css"type="text/css" /></head><body><divid="root"><divclass="container sample"><igc-treeid="tree"selection="cascade"></igc-tree></div></div><!-- This script is needed only for parcel and it will be excluded for webpack -->
<% if (false) { %><scriptsrc="src/index.ts"></script><% } %>
</body></html>html
/* shared styles are loaded from: *//* https://static.infragistics.com/xplatform/css/samples */css
Después de que el usuario hace clic en el icono de expansión, se reemplaza por un indicador de carga. Cuando la propiedad de carga se resuelve en falsa, el indicador de carga desaparece y se cargan los elementos secundarios.
Puede proporcionar un contenido de ranura personalizado para el área de carga utilizando la ranura loadingIndicator. Si dicha ranura no está definida, se utiliza IgcCircularProgressComponent.
Load On Demand With Virtualization
Cargar una mayor cantidad de elementos secundarios a pedido en la Ignite UI for Web Components podría afectar negativamente el rendimiento, ya que los elementos del árbol se definen de forma declarativa por diseño. La siguiente demostración muestra cómo se puede utilizar la biblioteca @lit-labs/virtualizer para representar los elementos del árbol secundario en un contenedor virtualizado. El resultado es un rendimiento mejorado, ya que solo la parte visible de los elementos secundarios se representa en el DOM.
EXAMPLE
Styling
Puede cambiar la apariencia de los IgcTreeItemComponent utilizando algunas de las partes CSS expuestas que se enumeran a continuación:
Nombre de la pieza
Descripción
wrapper
El contenedor del elemento del árbol.
selected
Indica el estado seleccionado. Se aplica awrapper.
focused
Indica estado enfocado. Se aplica awrapper.
active
Indica un estado activo. Se aplica awrapper.
indicator
El indicador de expansión del elemento del árbol.
label
El contenido del elemento del árbol.
text
El elemento del árbol mostraba texto.
select
La casilla de verificación del elemento del árbol cuando la selección está habilitada.
Usando estas partes CSS podemos personalizar la apariencia del componente IgcTreeComponent de esta manera: