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

    In this basic Angular Tree example, you can see how to define an igx-tree and its nodes by specifying the node hierarchy and iterating through a hierarchical data set.

    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.

    The next step is to import the IgxTreeModule in your app.module file.

    // app.module.ts
    
    ...
    import { IgxTreeModule } from 'igniteui-angular';
    // 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';
    // 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 {}
    

    Now that we have the Ignite UI for Angular Tree module or directives imported, let’s get started with a basic configuration of the igx-tree and its nodes.

    Using the Angular Tree

    IgxTreeNodesComponent is the representation of every node that belongs to the IgxTreeComponent.
    Nodes provide disabled, active, selected and expanded properties, which give you opportunity to configure the states of the node as per your requirement. data property can be used to add a reference to the data entry the node represents. Binding [data] is required for searching through nodes using 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>
    

    When a node should render a link, the IgxTreeNodeLink directive should be added to the <a> tag. This will ensure the proper aria role is assigned to the node's DOM elements.

    <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).
    • by clicking on the node if the igx-tree toggleNodeOnClick property is set to true.
    <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

    To create a reusable template for your nodes, declare <ng-template> within igx-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

    In order to setup node selection in the igx-tree, you just need to set its selection property. This property accepts the following three modes: None, BiState and Cascading. Below we will take a look at each of them in more detail.

    None

    In the igx-tree by default node selection is disabled. Users cannot select or deselect a node through UI interaction, but these actions can still be completed through the provided API method.

    Bi-State

    To enable bi-state node selection in the igx-tree just set the selection property to BiState. This will render a checkbox for every node. Each node has two states - selected or not. This mode supports multiple selection.

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

    Cascading

    To enable cascading node selection in the igx-tree, just set the selection property to Cascading. This will render a checkbox for every node.

    <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

    After the user clicks the expand icon, it is replaced by a loading indicator. When the loading property resolves to false, the loading indicator disappears and the children are loaded.

    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.

    Using the Ignite UI for Angular Theming, we can greatly alter the tree appearance. First, in order for us to use the functions exposed by the theme engine, we need to import the index file in our style file:

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

    Following the simplest approach, we create a new theme that extends the tree-theme and provide just the $background parameter, the theme will automatically calculate all the other necessary colors, of course you can override any of the other properties:

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

    Once applied, these classes enable dynamic theme calculations. You can then override the generated CSS variables using arbitrary properties. After the colon, provide any valid CSS color format (HEX, CSS variable, 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.