Descripción general del componente de árbol Angular

    El componente de árbol de Angular permite a los usuarios representar datos jerárquicos en una estructura de vista de árbol con 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 de árbol de Ignite UI for Angular también proporciona capacidades de carga bajo demanda, activación de elementos, selección en cascada de elementos de dos y tres estados a través de casillas de verificación integradas, navegación con teclado incorporada y más.

    Angular Tree Example

    En este ejemplo básico del Angular Árbol, puedes ver cómo definir unigx-tree nodo y sus nodos especificando la jerarquía de nodos e iterando a través de un conjunto de datos jerárquico.

    Getting Started with Ignite UI for Angular Tree

    Para comenzar con el componente Ignite UI for Angular Tree, primero debe instalar Ignite UI for Angular. En una aplicación Angular existente, escriba el siguiente comando:

    ng add igniteui-angular
    

    Para obtener una introducción completa al Ignite UI for Angular, lea el tema de introducción.

    El siguiente paso es importar elIgxTreeModule archivo en tu app.module.

    // app.module.ts
    
    ...
    import { IgxTreeModule } from 'igniteui-angular/tree';
    // import { IgxTreeModule } from '@infragistics/igniteui-angular'; for licensed package
    
    @NgModule({
        ...
        imports: [..., IgxTreeModule],
        ...
    })
    export class AppModule {}
    

    Alternativamente,16.0.0 puedes importarlosIgxTreeComponent como una dependencia independiente, o usar elIGX_TREE_DIRECTIVES token para importar el componente y todos sus componentes y directivas de soporte.

    // home.component.ts
    
    import { IGX_TREE_DIRECTIVES } from 'igniteui-angular/tree';
    // import { IGX_TREE_DIRECTIVES } from '@infragistics/igniteui-angular'; for licensed package
    
    @Component({
        selector: 'app-home',
        template: `
        <igx-tree>
            <igx-tree-node>
                Angular Libraries
                <igx-tree-node>Ignite UI for Angular</igx-tree-node>
                <igx-tree-node>Angular Material</igx-tree-node>
            </igx-tree-node>
            <igx-tree-node>
                Web Component Libraries
                <igx-tree-node>Ignite UI for Web Components</igx-tree-node>
                <igx-tree-node>Open UI 5</igx-tree-node>
            </igx-tree-node>
            <igx-tree-node>
                Blazor Libraries
                <igx-tree-node>Ignite UI for Blazor</igx-tree-node>
            </igx-tree-node>
        </igx-tree>
        `,
        styleUrls: ['home.component.scss'],
        standalone: true,
        imports: [IGX_TREE_DIRECTIVES]
        /* or imports: [IgxTreeComponent, IgxTreeNodeComponent] */
    })
    export class HomeComponent {}
    

    Ahora que hemos importado el módulo o directivas del Ignite UI for Angular Tree, empecemos con una configuración básica de losigx-tree y sus nodos.

    Using the Angular Tree

    IgxTreeNodesComponent es la representación de cada nodo que pertenece al IgxTreeComponent.
    Los nodos proporcionan propiedades deshabilitadas, activas, seleccionadas y expandidas, que te dan la oportunidad de configurar los estados del nodo según tus necesidades. La propiedad de datos puede usarse para añadir una referencia a la entrada de datos que representa el nodo. Se requiere binding[data] para buscar entre nodos usando IgxTreeComponent.findNodes().

    Declaring a tree

    Los nodos se pueden declarar utilizando uno de los siguientes enfoques.

    • Declarar el árbol y sus nodos especificando la jerarquía de nodos e iterando a través de un conjunto de datos
    <igx-tree>
     <igx-tree-node *ngFor="let node of data" [data]="node" [expanded]="isNodeExpaded(node)" [selected]="isNodeSelected(node)">
      {{ node.text }}
      <img [src]="node.image" [alt]="node.imageAlt" />
      <igx-tree-node *ngFor="let child of node.children" [data]="child" [expanded]="isNodeExpaded(child)" [selected]="isNodeSelected(child)">
                {{ child.text }}
      </igx-tree-node>
     </igx-tree-node>
    </igx-tree>
    

    Los nodos se pueden vincular a un modelo de datos para que sus estados expandidos y seleccionados también se reflejen en los datos subyacentes.

    <igx-tree (nodeSelection)="handleSelectionEvent($event)">
     <igx-tree-node *ngFor="let node of data" [data]="node" [(expanded)]="node.expanded" [(selected)]="node.selected">
      {{ node.text }}
      <img [src]="node.image" [alt]="node.imageAlt" />
      <igx-tree-node *ngFor="let child of node.children" [data]="child">
       <a igxTreeNodeLink [href]="child.url" target="_blank">
                    {{ child.text }}
                </a>
      </igx-tree-node>
     </igx-tree-node>
    </igx-tree>
    
    • Declarar un árbol creando nodos independientes estáticos

    Para representar un árbol no es necesario necesariamente un conjunto de datos: se pueden crear nodos individuales sin un modelo de datos subyacente:

    <igx-tree>
     <igx-tree-node [expanded]="true" [selected]="false">
      I am a parent node 1
      <img src="hard_coded_src.webb" alt="Alt Text" />  
      <igx-tree-node [expanded]="true" [selected]="false">
       I am a child node 1
       <igx-tree-node>
        <a igxTreeNodeLink href="https://google.com" target="_blank">
            I am a child node of the child
        </a>
       </igx-tree-node>
      </igx-tree-node>
     </igx-tree-node>
    
     <igx-tree-node [expanded]="false" [selected]="false">
      I am a parent node 2
      <img src="hard_coded_src.webb" alt="Alt Text" />
            <igx-tree-node [expanded]="false" [selected]="false">
       I am a child node 1
      </igx-tree-node>
     </igx-tree-node>
    
        <igx-tree-node [selected]="false" [disabled]="true">
      I am a parent node 3
     </igx-tree-node>
    </igx-tree>
    

    Cuando un nodo debe renderizar un enlace, laIgxTreeNodeLink directiva debe añadirse a la<a> etiqueta. Esto asegurará que se asigne el rol adecuado de aria a los elementos DOM del nodo.

    <igx-tree>
     <igx-tree-node *ngFor="let node of data" [data]="node" [expanded]="isNodeExpaded(node)" [selected]="isNodeSelected(node)">
      {{ node.text }}
      <img [src]="node.image" [alt]="node.imageAlt" />
      <igx-tree-node *ngFor="let child of node.children" [data]="child">
                <a igxTreeNodeLink [href]="child.url" target="_blank">
                    {{ child.text }}
                </a>
      </igx-tree-node>
     </igx-tree-node>
    </igx-tree>
    

    Node Interactions

    IgxTreeNodeComponent podría expandirse o contraerse:

    • Al hacer clic en el nodo, expanda el indicador (comportamiento predeterminado).
    • haciendo clic en el nodo si laigx-tree propiedad toggleNodeOnClick está configurada comotrue.
    <igx-tree [toggleNodeOnClick]="true">
     <igx-tree-node *ngFor="let node of data" [data]="node">
      {{ node.text }}
      <igx-tree-node *ngFor="let child of node.children" [data]="child">
                    {{ child.text }}
      </igx-tree-node>
     </igx-tree-node>
    </igx-tree>
    

    De forma predeterminada, se pueden expandir varios nodos al mismo tiempo. Para cambiar este comportamiento y permitir la expansión de una sola rama a la vez, se podría habilitar la propiedad singleBranchExpand. De esta manera, cuando se expande un nodo, se contraerán todas las demás ramas ya expandidas en el mismo nivel.

    <igx-tree [singleBranchExpand]="true">
     <igx-tree-node *ngFor="let node of data" [data]="node">
      {{ node.text }}
      <igx-tree-node *ngFor="let child of node.children" [data]="child">
                    {{ child.text }}
      </igx-tree-node>
     </igx-tree-node>
    </igx-tree>
    

    Además, IgxTree proporciona los siguientes métodos de API para las interacciones de nodos:

    • expandir: expande el nodo con animación.
    • colapso: colapsa el nodo con animación.
    • alternar: alterna el estado de expansión del nodo con animación.
    • colapsoTodo: colapsa los nodos especificados con animación. Si no se pasa ningún nodo, colapsa todos los nodos principales.
    • expandAll: establece los nodos especificados como expandidos con animación. Si no se pasa ningún nodo, expande todos los nodos principales.
    • deselectAll: anula la selección de todos los nodos. Si se pasa una matriz de nodos, anula la selección solo de los nodos especificados. No emite el evento nodeSelection.

    Finding Nodes

    Puede encontrar un nodo específico dentro de un IgxTree utilizando el método findNodes. Devuelve una matriz de nodos que coinciden con los datos especificados. Al buscar nodos en escenarios de estructura de datos más complejos, como claves primarias compuestas, puede pasar una función de comparación personalizada para especificar los criterios para buscar nodos en función de los datos.

    <igx-tree>
     <igx-tree-node *ngFor="let node of data" [data]="node" [expanded]="isNodeExpaded(node)" [selected]="isNodeSelected(node)">
      {{ node.text }}
      <img [src]="node.image" alt="node.imageAlt" />
      <igx-tree-node *ngFor="let child of node.children" [data]="child" [expanded]="isNodeExpaded(child)" [selected]="isNodeSelected(child)">
                {{ child.text }}
      </igx-tree-node>
     </igx-tree-node>
    </igx-tree>
    
    export class MyTreeViewComponent {
      public data: { [key: string]: any, valueKey: string } = MY_DATA;
      @ViewChild(IgxTreeComponent, { read: IgxTreeComponent })
      public tree;
    
      findNode(valueKey: string) {
        const comparer: IgxTreeSearchResolver =
          (data: any, node: IgxTreeNodeComponent) => node.data.valueKey === data;
        const matchingNodes: IgxTreeNode<{ [key: string]: any, valueKey: string }>[] = this.tree.findNodes(valueKey, comparer);
      }
    }
    

    Templating

    Para crear una plantilla reutilizable para tus nodos, declara<ng-template> dentro de ellosigx-tree.

    <igx-tree>
        <igx-tree-node *ngFor="let node of data" [data]="node">
            <ng-container *ngTemplateOutlet="#nodeTemplate; context: { $implicit: node }"></ng-container>
            <igx-tree-node *ngFor="let child of node.ChildCompanies" [data]="child">
                <ng-container *ngTemplateOutlet="#nodeTemplate; context: { $implicit: child}"></ng-container>
            </igx-tree-node>
        </igx-tree-node>
        <ng-template #nodeTemplate let-data>
            <div class="node-header company">
                <igx-icon class="company__logo">{{ data.Logo }}</igx-icon>
                <div class="company__name">{{ data.CompanyName }}</div>
            </div>
        </ng-template>
    </igx-tree>
    

    Además, al utilizar la entrada expandIndicator, tiene la capacidad de configurar una plantilla personalizada que se utilizará para representar los indicadores de expansión/contraer de los nodos.

    <igx-tree>
        <igx-tree-node *ngFor="let node of data" [data]="node">
        </igx-tree-node>
        <ng-template igxTreeExpandIndicator let-expanded>
            <igx-icon>{{ expanded ? 'expand_less' : 'expand_more' }}</igx-icon>
        </ng-template>
    </igx-tree>
    

    Angular Tree Selection

    Para configurar la selección de nodos en eligx-tree, solo necesitas establecer su propiedad de selección. Esta propiedad acepta los siguientes tres modos: Ninguno, BiState y Cascada. A continuación, analizaremos cada uno de ellos con más detalle.

    None

    Por defecto,igx-tree la selección de nodos está desactivada. Los usuarios no pueden seleccionar ni deseleccionar un nodo mediante la interacción con la interfaz, pero estas acciones aún pueden completarse mediante el método de API proporcionado.

    Bi-State

    Para permitir la selección de nodos bi-estados en eligx-tree solo establece la propiedad de selección en BiState. Esto mostrará una casilla de verificación para cada nodo. Cada nodo tiene dos estados: seleccionados o no. Este modo permite selección múltiple.

    <igx-tree selection="BiState">
    </igx-tree>
    

    Cascading

    Para permitir la selección de nodos en cascada en eligx-tree, simplemente establece la propiedad de selección en Cascada. Esto mostrará una casilla de verificación para cada nodo.

    <igx-tree selection="Cascading">
    </igx-tree>
    

    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.

    Angular Tree Checkbox

    El componente Árbol de Angular proporciona soporte integrado para casillas de verificación, lo que permite a los usuarios seleccionar más de un elemento.

    Las casillas de verificación de TreeView también tienen un modo de tres estados, que se aplica solo a los nodos principales parcialmente seleccionados. En este modo, un nodo principal pasará al estado indeterminado cuando se marquen algunos, pero no todos, los nodos secundarios.

    Keyboard Navigation

    La navegación con el teclado en IgxTree 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 nodos.

    La navegación IgxTree cumple con los estándares de accesibilidad del W3C y es cómoda de usar.

    Combinaciones de teclas

    • Flecha hacia abajo: navega al siguiente nodo visible. Marca el nodo como activo. No hace nada si está en el ÚLTIMO nodo
    • Ctrl + Flecha hacia abajo: navega al siguiente nodo visible. No hace nada si está en el ÚLTIMO nodo
    • Flecha hacia arriba: navega al nodo visible anterior. Marca el nodo como activo. No hace nada si está en el PRIMER nodo
    • Ctrl + Flecha arriba: navega al nodo visible anterior. No hace nada si está en el PRIMER nodo
    • Flecha izquierda: en un nodo principal expandido, lo contrae. Si está en un nodo secundario, se mueve a su nodo principal.
    • Flecha hacia la derecha: en un nodo principal expandido, navega hasta el primer hijo del nodo. Si se encuentra en un nodo principal colapsado, lo expande.
    • Inicio: navega al PRIMER nodo
    • Fin: navega hasta el ÚLTIMO nodo visible
    • Pestaña: navega al siguiente elemento enfocable en la página, fuera del árbol
    • Shift + Tab: navega al elemento enfocable anterior en la página, fuera del árbol
    • Espacio: alterna la selección del nodo actual. Marca el nodo como activo.
    • Mayús + Espacio: alterna la selección de todos los nodos entre el activo y el que se presionó Espacio mientras se mantiene presionada la tecla Mayús si la selección está habilitada.
    • Enter: activa el nodo enfocado. Si el nodo tiene un enlace, abra el enlace.
    • *- expande el nodo y todos los nodos hermanos en el mismo nivel

    Cuando la selección está habilitada, la selección de nodos 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 mouse + teclado:

    • Hacer clic: cuando se realiza en la casilla de verificación del nodo, alterna la selección del nodo si la selección está habilitada. De lo contrario, enfoca el nodo.
    • Mayús + clic: cuando se realiza en la casilla de verificación del nodo, alterna la selección de todos los nodos entre el activo y el que se hizo clic mientras se mantiene presionada la tecla Mayús si la selección está habilitada.

    Angular Tree Load On Demand

    El Ignite UI for Angular IgxTree se puede representar de tal manera que requiera que se recupere 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 nodo, se recuperarán los elementos secundarios de ese nodo principal en particular. Este mecanismo, también conocido como Load on Demand, se puede configurar fácilmente para trabajar con cualquier dato remoto.

    Demo

    Después de que el usuario haga clic en el icono de expandir, este se reemplaza por un indicador de carga. Cuando la propiedad de carga se resuelve a,false el indicador de carga desaparece y los hijos se cargan.

    Estilismo

    Tree Theme Property Map

    Al modificar una propiedad principal, todas las propiedades dependientes relacionadas se actualizan automáticamente para reflejar el cambio:

    Propiedad principal Propiedad dependiente Descripción
    $background
    $foreground El color utilizado para el contenido del nodo del árbol.
    $background-seleccionadoEl color de fondo utilizado para el nodo del árbol seleccionado.
    $hover colorEl color de fondo usado para el nodo árbol al pasar el cursor.
    $background activoEl color de fondo usado para el nodo activo del árbol.
    $background discapacitadoEl color de fondo usado para el nodo árbol en estado desactivado.
    $background-seleccionado
    $foreground seleccionado El color utilizado para el contenido del nodo del árbol seleccionado.
    $hover-color-seleccionadoEl color de fondo usado para el nodo de árbol seleccionado al pasar el cursor.
    $background activo
    $foreground-activo El color utilizado para el contenido del nodo activo del árbol.
    $background-activo-seleccionadoEl color de fondo utilizado para el nodo activo seleccionado del árbol.
    $background-activo-seleccionado $foreground-activo-seleccionado El color utilizado para el contenido del nodo activo seleccionado en el árbol.
    $background discapacitado $foreground discapacitado El color utilizado para el contenido del nodo árbol deshabilitado.

    Usando la Ignite UI for Angular Theming, podemos alterar mucho la apariencia del árbol. Primero, para que podamos usar las funciones expuestas por el motor de temas, necesitamos importar elindex archivo en nuestro archivo de estilo:

    @use "igniteui-angular/theming" as *;
    
    // IMPORTANT: Prior to Ignite UI for Angular version 13 use:
    // @import '~igniteui-angular/lib/core/styles/themes/index';
    

    Siguiendo el enfoque más sencillo, creamos un nuevo tema que extiende el tema de árbol y proporciona solo el$background parámetro, el tema calculará automáticamente todos los demás colores necesarios, por supuesto puedes anular cualquiera de las otras propiedades:

    $custom-tree-theme: tree-theme(
      $background: #ecaa53,
    );
    

    El último paso es incluir el tema del componente.

    @include css-vars($custom-tree-theme);
    

    Demo

    Styling with Tailwind

    Puedes decorar el árbol usando nuestras clases utilitarias personalizadas de Tailwind. Asegúrate de configurar primero a Tailwind.

    Junto con la importación de Tailwind en tu hoja de estilos global, puedes aplicar las utilidades de tema deseadas de la siguiente manera:

    @import "tailwindcss";
    ...
    @use 'igniteui-theming/tailwind/utilities/material.css';
    

    El archivo de utilidad incluye variantes tantolight comodark de tema.

    • Usalight-* clases para el tema ligero.
    • Usadark-* clases para el tema oscuro.
    • Añadir el nombre del componente después del prefijo, por ejemplo, ,light-tree,dark-tree.

    Una vez aplicadas, estas clases permiten cálculos dinámicos de temas. Luego puedes anular las variables CSS generadas usandoarbitrary properties. Después de los dos puntos, proporciona cualquier formato de color CSS válido (HEX, variable CSS, RGB, etc.).

    Puedes encontrar la lista completa de propiedades en el tema IgxTree. La sintaxis es la siguiente:

    <igx-tree class="tree-root">
        @for (type of data; track type) {
          <igx-tree-node class="!light-tree ![--background:#81B698]">
            {{ type.Name }}
            @for (value of type.Children; track value) {
              <igx-tree-node class="!light-tree ![--background:#81B698]">
                {{ value.Name }}
              </igx-tree-node>
            }
          </igx-tree-node>
        }
    </igx-tree>
    
    Note

    El signo de exclamación(!) es necesario para asegurar que la clase de utilidad tenga prioridad. Tailwind aplica estilos en capas y, sin marcar estos estilos como importantes, serán anulados por el tema predeterminado del componente.

    Al final, tu árbol debería quedar así:

    Known Issues and Limitations

    Limitación Descripción
    Nodos de plantilla recursivos Eligx-tree no admite la creación recursiva de nodos de árbol igx mediante plantilla. Obtenga más información. Todos los nodos deben declararse manualmente, lo que significa que si desea visualizar una jerarquía muy profunda, esto afectaría el tamaño de su archivo de plantilla. El árbol está destinado a ser utilizado principalmente como componente de diseño/navegación. Si es necesario visualizar una fuente de datos jerárquica con numerosos niveles de profundidad y datos homogéneos, puede utilizar IgxTreeGrid
    Usando IgxTreeNodes con el antiguo View Engine (anterior a Ivy) Hay un problema en el motor de visualización de Angular (anterior a Ivy) que impide que se use el árbol cuandoenableIvy: false se establece en tsconfig.json
    Navegación por pestañas en Firefox Al acceder al árbol mediante la navegación con el teclado, cuando el árbol tiene una barra de desplazamiento, primero se enfocará el elemento igx-tree-node. Este es el comportamiento predeterminado en FireFox, sin embargo, se puede resolver poniendo un comando explícitotabIndex = -1 en el árbol.

    API References

    Additional Resources

    Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.