Descripción general del componente de vista de lista Angular
El componente Ignite UI for Angular List muestra filas de elementos y admite uno o más elementos de encabezado, así como la búsqueda y el filtrado de elementos de la lista. Cada elemento de la lista es completamente adaptable y admite cualquier componente HTML o Angular válido. El componente de lista también proporciona funciones de panorámica integradas, plantillas para estados vacíos y de carga, y admite virtualización para listas grandes mediante la directiva IgxForOf
.
Angular List Example
El siguiente ejemplo representa una lista llena de contactos con propiedades de nombre y número de teléfono . El componente IgxList
utiliza igx-avatar
e igx-icon
para enriquecer la experiencia del usuario y exponer las capacidades de configurar una imagen de avatar y un ícono diferente para marcar un contacto como favorito. Además, la Vista de lista expone las capacidades de clasificación logradas mediante el uso de nuestro canal de filtrado.
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxAvatarModule,
IgxFilterModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule,
IgxButtonGroupModule,
IgxRippleModule
} from "igniteui-angular" ;
import { ListSample4Component } from "./list-sample-4/list-sample-4.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample4Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxAvatarModule,
IgxFilterModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule,
IgxButtonGroupModule,
IgxRippleModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component, HostBinding, OnInit } from '@angular/core' ;
import { IgxFilterOptions } from 'igniteui-angular' ;
@Component ({
selector : 'app-contact-list2' ,
styleUrls : ['./list-sample-4.component.scss' ],
templateUrl : './list-sample-4.component.html'
})
export class ListSample4Component implements OnInit {
public searchContact: string ;
public contacts = [
{
isFavorite : false ,
name : 'Terrance Orta' ,
phone : '770-504-2217' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/27.jpg'
},
{
isFavorite : true ,
name : 'Richard Mahoney' ,
phone : '423-676-2869' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/1.jpg'
},
{
isFavorite : false ,
name : 'Donna Price' ,
phone : '859-496-2817' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/50.jpg'
},
{
isFavorite : false ,
name : 'Lisa Landers' ,
phone : '901-747-3428' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/3.jpg'
},
{
isFavorite : true ,
name : 'Dorothy H. Spencer' ,
phone : '573-394-9254' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/67.jpg'
}
];
public size = 'large' ;
public sizes;
constructor ( ) { }
public ngOnInit ( ) {
this .sizes = [
{ label : 'large' , selected : this .size === 'large' , togglable : true },
{ label : 'medium' , selected : this .size === 'medium' , togglable : true },
{ label : 'small' , selected : this .size === 'small' , togglable : true }
];
}
@HostBinding ('style.--ig-size' )
protected get sizeStyle () {
return `var(--ig-size-${this .size} )` ;
}
public selectSize (event ) {
this .size = this .sizes[event.index].label;
}
public toggleFavorite (contact: any , event: Event ) {
event.stopPropagation();
contact.isFavorite = !contact.isFavorite;
}
get filterContacts () {
const fo = new IgxFilterOptions();
fo.key = 'name' ;
fo.inputValue = this .searchContact;
return fo;
}
public mousedown (event: Event ) {
event.stopPropagation();
}
}
ts コピー <div class ="density-chooser" >
<igx-buttongroup [values ]="sizes" (selected )="selectSize($event)" > </igx-buttongroup >
</div >
<igx-input-group type ="search" class ="search" >
<igx-prefix >
<igx-icon > search</igx-icon >
</igx-prefix >
<input #search igxInput placeholder ="Search Contacts" [(ngModel )]="searchContact" >
<igx-suffix *ngIf ="search.value.length > 0" (click )="searchContact = null" >
<igx-icon > clear</igx-icon >
</igx-suffix >
</igx-input-group >
<div class ="list-sample" >
<igx-list >
<igx-list-item [isHeader ]="true" > Contacts</igx-list-item >
<igx-list-item igxRipple igxRippleTarget =".igx-list__item-content" #item
*ngFor ="let contact of contacts | igxFilter: filterContacts;" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<span igxListLineTitle > {{ contact.name }}</span >
<span igxListLineSubTitle > {{ contact.phone }}</span >
<igx-icon igxListAction [style.color ]="contact.isFavorite ? 'orange' : 'lightgray'" igxRipple ="pink"
[igxRippleCentered ]="true" (click )="toggleFavorite(contact, $event)"
(mousedown )="mousedown($event)" > star</igx-icon >
</igx-list-item >
</igx-list >
</div >
html コピー :host {
display : block;
padding : 16px ;
}
.list-sample {
box-shadow : 0px 1px 3px 0px rgba(0 , 0 , 0 , 0.2 ),
0px 1px 1px 0px rgba(0 , 0 , 0 , 0.14 ),
0px 2px 1px -1px rgba(0 , 0 , 0 , 0.12 );
}
.density-chooser {
margin-bottom : 16px ;
}
igx-icon {
cursor : pointer;
position : relative;
}
.search {
margin-bottom : 16px ;
}
scss コピー
Like this sample? Get access to our complete Ignite UI for Angular toolkit and start building your own apps in minutes. Download it for free.
Getting Started with Ignite UI for Angular List
Para comenzar con el componente Ignite UI for Angular List View, primero debe instalar Ignite UI for Angular. En una aplicación Angular existente, escriba el siguiente comando:
ng add igniteui-angular
cmd
Para obtener una introducción completa a la Ignite UI for Angular, lea el tema de introducción .
El siguiente paso es importar IgxListModule
en el archivo app.module.ts .
Este componente puede utilizar el HammerModule
opcionalmente . Se puede importar en el módulo raíz de la aplicación para que las interacciones táctiles funcionen como se espera.
import { HammerModule } from '@angular/platform-browser' ;
import { IgxListModule } from 'igniteui-angular' ;
@NgModule ({
...
imports : [..., IgxListModule, HammerModule],
...
})
export class AppModule {}
typescript
Alternativamente, a partir de 16.0.0
, puede importar IgxListComponent
como una dependencia independiente o usar el token IGX_LIST_DIRECTIVES
para importar el componente y todos sus componentes y directivas de soporte.
import { HammerModule } from '@angular/platform-browser' ;
import { IGX_LIST_DIRECTIVES } from 'igniteui-angular' ;
@Component ({
selector : 'app-home' ,
template : `
<igx-list>
<igx-list-item isHeader="true">Header</igx-list-item>
<igx-list-item>Item 1</igx-list-item>
<igx-list-item>Item 2</igx-list-item>
<igx-list-item>Item 3</igx-list-item>
</igx-list>
` ,
styleUrls : ['home.component.scss' ],
standalone : true ,
imports : [IGX_LIST_DIRECTIVES, HammerModule]
})
export class HomeComponent {}
typescript
Ahora que ha importado la Ignite UI for Angular List, puede comenzar a usar el componente igx-list
.
Using the Angular List
Luego, en la plantilla de nuestro componente de contactos podemos crear nuestra lista, pero ¿qué pasa si actualmente (o en algún momento en el futuro) no tenemos elementos en ella? En este caso, la lista Angular nos proporciona una plantilla predeterminada que se utiliza cuando la lista está vacía. Siempre podemos proporcionar nuestra propia plantilla para el aspecto de nuestra lista vacía simplemente usando la directiva igxEmptyList
. En este caso, no se utilizará la plantilla predeterminada:
<igx-list >
<ng-template igxEmptyList >
<p class ="empty" > No contacts! :(</p >
</ng-template >
</igx-list >
html
Y nuestro estilo para la plantilla vacía:
.empty {
color : rgba (0 , 153 , 255 , 1 );
font-size : 25px ;
font-weight : 600 ;
text-shadow : 2px 1px 2px rgba (150 , 150 , 150 , 1 );
}
css
Si todo salió bien, así es como debería verse nuestra lista vacía:
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import { IgxListModule } from "igniteui-angular" ;
import { ListSample5Component } from "./list-sample-5/list-sample-5.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample5Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxListModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component } from '@angular/core' ;
@Component ({
selector : 'app-list-sample-5' ,
styleUrls : ['./list-sample-5.component.scss' ],
templateUrl : './list-sample-5.component.html'
})
export class ListSample5Component {
constructor ( ) { }
}
ts コピー <igx-list >
<ng-template igxEmptyList >
<p class ="empty" > No contacts! :(</p >
</ng-template >
</igx-list >
html コピー .empty {
color : rgba(0 , 153 , 255 , 1 );
font-size : 25px ;
font-weight : 600 ;
text-shadow : 2px 1px 2px rgba(150 , 150 , 150 , 1 );
}
scss コピー
A veces puede haber un retraso en la carga de datos. En este caso, puede establecer la propiedad isLoading
de la lista en true
y una plantilla predeterminada informará al usuario sobre el proceso de carga de datos en curso. También puedes proporcionar tu propia plantilla de carga usando la directiva igxDataLoading
:
<igx-list >
<ng-template igxDataLoading >
<p class ="loading" > Patience, we are currently loading your data...</p >
</ng-template >
</igx-list >
html
.loading {
color : rgba (255 , 153 , 0 , 1 );
font-size : 25px ;
font-weight : 600 ;
text-shadow : 2px 1px 2px rgba (150 , 150 , 150 , 1 );
}
css
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxButtonModule,
IgxListModule,
IgxRippleModule
} from "igniteui-angular" ;
import { ListSample6Component } from "./list-sample-6/list-sample-6.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample6Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxButtonModule,
IgxListModule,
IgxRippleModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component, ViewChild } from '@angular/core' ;
import { IgxListComponent } from 'igniteui-angular' ;
@Component ({
selector : 'app-list-sample-6' ,
styleUrls : ['./list-sample-6.component.scss' ],
templateUrl : './list-sample-6.component.html'
})
export class ListSample6Component {
@ViewChild ('fruitList' , { static : true })
public fruitList: IgxListComponent;
public fruitsData: string [] = [];
constructor ( ) { }
public loadFruits ( ) {
this .fruitList.isLoading = true ;
setTimeout (() => {
const availableFruits: string [] = ['banana' , 'orange' , 'apple' , 'strawberry' , 'pear' ];
availableFruits.forEach((fruit ) => { this .fruitsData.push(fruit); });
this .fruitList.isLoading = false ;
}, 1000 );
}
}
ts コピー <igx-list #fruitList >
<igx-list-item *ngFor ="let fruit of fruitsData" igxRipple igxRippleTarget =".igx-list__item-content" >
{{ fruit }}
</igx-list-item >
<ng-template igxEmptyList >
<div class ="center" > <button type ="button" igxButton ="contained" (click )="loadFruits()" > Load data</button > </div >
</ng-template >
<ng-template igxDataLoading >
<div class ="center" > <span > Patience, we are currently loading your data...</span > </div >
</ng-template >
</igx-list >
html コピー .center {
display : flex;
align-items : center;
justify-content : center;
color : #999 ;
font-size : 24px ;
height : 100% ;
}
scss コピー
Add List Items
Es bueno tener una plantilla para cuando la lista esté vacía, ¡pero ahora agreguemos algunos elementos! Podemos agregar el siguiente código para obtener una lista simple de elementos:
<igx-list >
<igx-list-item isHeader ="true" > Header</igx-list-item >
<igx-list-item > Item 1</igx-list-item >
<igx-list-item > Item 2</igx-list-item >
<igx-list-item > Item 3</igx-list-item >
</igx-list >
html
Si todo ha ido bien deberías ver lo siguiente en tu navegador:
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import { IgxListModule } from "igniteui-angular" ;
import { ListSample2Component } from "./list-sample-2/list-sample-2.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample2Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxListModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component } from '@angular/core' ;
@Component ({
selector : 'app-igx-list-simple' ,
styleUrls : ['./list-sample-2.component.scss' ],
templateUrl : './list-sample-2.component.html'
})
export class ListSample2Component {
constructor ( ) {}
}
ts コピー <igx-list >
<igx-list-item [isHeader ]="true" > Header</igx-list-item >
<igx-list-item > Item 1</igx-list-item >
<igx-list-item > Item 2</igx-list-item >
<igx-list-item > Item 3</igx-list-item >
</igx-list >
html コピー
Mejoremos un poco nuestro juego y mejoremos los elementos de nuestra lista. Digamos que queremos crear una lista Angular de contactos con un nombre y un número de teléfono debajo del nombre. En nuestro archivo mecanografiado de componentes podemos definir una lista de contactos:
...
public contacts = [{
name : "Terrance Orta" ,
phone : "770-504-2217"
}, {
name : "Richard Mahoney" ,
phone : "423-676-2869"
}, {
name : "Donna Price" ,
phone : "859-496-2817"
}, {
name : "Lisa Landers" ,
phone : "901-747-3428"
}, {
name : "Dorothy H. Spencer" ,
phone : "573-394-9254"
}];
typescript
Ahora que tenemos algunos datos que queremos representar, configuremos algunas marcas. Si queremos algo de estilo listo para usar, podemos usar algunas de las directivas que vienen con los elementos de la lista.
Veamos cómo podemos usar algunos de ellos en el siguiente ejemplo:
<igx-list >
<igx-list-item isHeader ="true" >
Contacts
</igx-list-item >
<igx-list-item *ngFor ="let contact of contacts" >
<h4 igxListLineTitle > {{ contact.name }}</h4 >
<p igxListLineSubTitle > {{ contact.phone }}</p >
</igx-list-item >
</igx-list >
html
Ambas directivas igxListLineTitle
e igxListLineSubTitle
le dan a los elementos de nuestra lista una apariencia predeterminada.
Después de todo eso, nuestra lista Angular ahora debería verse así:
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxListModule,
IgxRippleModule
} from "igniteui-angular" ;
import { ListSample3Component } from "./list-sample-3/list-sample-3.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample3Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxListModule,
IgxRippleModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component } from '@angular/core' ;
@Component ({
selector : 'app-contact-list' ,
styleUrls : ['./list-sample-3.component.scss' ],
templateUrl : './list-sample-3.component.html'
})
export class ListSample3Component {
public contacts = [
{
name : 'Terrance Orta' ,
phone : '770-504-2217'
},
{
name : 'Richard Mahoney' ,
phone : '423-676-2869'
},
{
name : 'Donna Price' ,
phone : '859-496-2817'
},
{
name : 'Lisa Landers' ,
phone : '901-747-3428'
},
{
name : 'Dorothy H. Spencer' ,
phone : '573-394-9254'
}
];
constructor ( ) { }
}
ts コピー <igx-list >
<igx-list-item [isHeader ]="true" >
Contacts
</igx-list-item >
<igx-list-item *ngFor ="let contact of contacts" igxRipple igxRippleTarget =".igx-list__item-content" >
<span igxListLineTitle > {{ contact.name }}</span >
<span igxListLineSubTitle > {{contact.phone}}</span >
</igx-list-item >
</igx-list >
html コピー
Adding Avatar and Icons
Podemos usar algunos de nuestros otros componentes junto con el componente IgxList
para enriquecer la experiencia y agregar algunas funciones. Podemos tener una bonita imagen de avatar a la izquierda del nombre y los valores del teléfono. Además, podemos agregar un ícono de estrella a la derecha de ellos para permitir al usuario marcar un contacto como favorito. Para hacer eso, tomemos los módulos IgxAvatar e IgxIcon e importemoslos en nuestro archivo app.module.ts.
...
import {
IgxListModule,
IgxAvatarModule,
IgxIconModule
} from 'igniteui-angular' ;
@NgModule ({
...
imports : [..., IgxAvatarModule, IgxIconModule],
})
export class AppModule {}
typescript
A continuación, debemos agregar más información a nuestro objeto de contacto, como una fuente photo
para nuestro avatar y una propiedad isFavorite
para indicar el estado favorito del contacto.
public contacts = [{
name : 'Terrance Orta' ,
phone : '770-504-2217' ,
photo : 'https://randomuser.me/api/portraits/men/27.jpg' ,
isFavorite : false
}, {
name : 'Richard Mahoney' ,
phone : '423-676-2869' ,
photo : 'https://randomuser.me/api/portraits/men/1.jpg' ,
isFavorite : true
}, {
name : 'Donna Price' ,
phone : '859-496-2817' ,
photo : 'https://randomuser.me/api/portraits/women/50.jpg' ,
isFavorite : false
}, {
name : 'Lisa Landers' ,
phone : '901-747-3428' ,
photo : 'https://randomuser.me/api/portraits/women/3.jpg' ,
isFavorite : false
}, {
name : 'Dorothy H. Spencer' ,
phone : '573-394-9254' ,
photo : 'https://randomuser.me/api/portraits/women/67.jpg' ,
isFavorite : true
}];
typescript
Genial, ahora actualicemos la plantilla de nuestra lista de contactos para mostrar el avatar y el ícono. Nuevamente podemos hacerlo usando algunas de las directivas de lista.
<igx-list >
<igx-list-item isHeader ="true" >
Contacts
</igx-list-item >
<igx-list-item #item *ngFor ="let contact of contacts;" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<h4 igxListLineTitle > {{ contact.name }}</h4 >
<p igxListLineSubTitle class ="phone" > {{ contact.phone }}</p >
<span igxListLine > Lorem ipsum dolor sit amet, consectetur adipisicing elit. Dicta, laborum.</span >
<igx-icon igxListAction [color ]="contact.isFavorite ? 'orange' : 'lightgray'" (click )="toggleFavorite(item)" > star</igx-icon >
</igx-list-item >
</igx-list >
html
igxListThumbnail
está diseñado para usarse si necesitamos agregar algún tipo de medio al principio de los elementos de nuestra lista. La directiva envolverá el elemento de destino en nuestro caso, igx-avatar, en un contenedor que proporcionará una posición y un espaciado predeterminados.
igxListAction
está destinado a usarse para elementos de lista que tienen algún tipo de acción o metadatos, por ejemplo, interruptor, botón de opción, casilla de verificación, etc. En nuestro caso, la acción estará representada por un igx-icon
. Nuevamente, la directiva envolverá el elemento de destino en un contenedor que tendrá la posición y el espaciado correctos.
igxListLine
está diseñado para usarse si necesitamos algo de texto entre igxListThumbnail
e igxListAction
, la directiva se asegurará de que la posición, el espaciado y la alineación del texto se verán geniales con las otras dos directivas.
A continuación, escuchamos un evento de clic en el componente IgxIcon para alternar la propiedad isFavorite en nuestro objeto de contacto.
...
toggleFavorite (item: IgxListItem ) {
const contact = this .contacts[item.index - 1 ];
contact.isFavorite = !contact.isFavorite;
}
typescript
También permitamos que el usuario elija el tamaño de la lista utilizando la propiedad personalizada CSS--ig-size
. Haremos esto importando IgxButtonGroupModule
y usando IgxButtonGroup para mostrar todos los valores de tamaño. De esta manera, cada vez que se seleccione uno, actualizaremos el tamaño de la lista.
...
import { IgxButtonGroupModule } from 'igniteui-angular' ;
@NgModule ({
imports : [..., IgxButtonGroupModule]
})
typescript
<igx-buttongroup [values ]="sizes" (selected )="selectSize($event)" > </igx-buttongroup >
...
<igx-list >
...
</igx-list >
html
public size = 'large' ;
public sizes;
public ngOnInit ( ) {
this .sizes = [
{ label : 'large' , selected : this .size === 'large' , togglable : true },
{ label : 'medium' , selected : this .size === 'medium' , togglable : true },
{ label : 'small' , selected : this .size === 'small' , togglable : true }
];
}
public selectSize (event: any ) {
this .size = this .sizes[event.index].label;
}
@HostBinding ('style.--ig-size' )
protected get sizeStyle () {
return `var(--ig-size-${this .size} )` ;
}
typescript
Y aquí está el resultado de todo ese trabajo:
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxAvatarModule,
IgxFilterModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule,
IgxButtonGroupModule,
IgxRippleModule
} from "igniteui-angular" ;
import { ListSample4Component } from "./list-sample-4/list-sample-4.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample4Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxAvatarModule,
IgxFilterModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule,
IgxButtonGroupModule,
IgxRippleModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component, HostBinding, OnInit } from '@angular/core' ;
import { IgxFilterOptions } from 'igniteui-angular' ;
@Component ({
selector : 'app-contact-list2' ,
styleUrls : ['./list-sample-4.component.scss' ],
templateUrl : './list-sample-4.component.html'
})
export class ListSample4Component implements OnInit {
public searchContact: string ;
public contacts = [
{
isFavorite : false ,
name : 'Terrance Orta' ,
phone : '770-504-2217' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/27.jpg'
},
{
isFavorite : true ,
name : 'Richard Mahoney' ,
phone : '423-676-2869' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/1.jpg'
},
{
isFavorite : false ,
name : 'Donna Price' ,
phone : '859-496-2817' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/50.jpg'
},
{
isFavorite : false ,
name : 'Lisa Landers' ,
phone : '901-747-3428' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/3.jpg'
},
{
isFavorite : true ,
name : 'Dorothy H. Spencer' ,
phone : '573-394-9254' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/67.jpg'
}
];
public size = 'large' ;
public sizes;
constructor ( ) { }
public ngOnInit ( ) {
this .sizes = [
{ label : 'large' , selected : this .size === 'large' , togglable : true },
{ label : 'medium' , selected : this .size === 'medium' , togglable : true },
{ label : 'small' , selected : this .size === 'small' , togglable : true }
];
}
@HostBinding ('style.--ig-size' )
protected get sizeStyle () {
return `var(--ig-size-${this .size} )` ;
}
public selectSize (event ) {
this .size = this .sizes[event.index].label;
}
public toggleFavorite (contact: any , event: Event ) {
event.stopPropagation();
contact.isFavorite = !contact.isFavorite;
}
get filterContacts () {
const fo = new IgxFilterOptions();
fo.key = 'name' ;
fo.inputValue = this .searchContact;
return fo;
}
public mousedown (event: Event ) {
event.stopPropagation();
}
}
ts コピー <div class ="density-chooser" >
<igx-buttongroup [values ]="sizes" (selected )="selectSize($event)" > </igx-buttongroup >
</div >
<igx-input-group type ="search" class ="search" >
<igx-prefix >
<igx-icon > search</igx-icon >
</igx-prefix >
<input #search igxInput placeholder ="Search Contacts" [(ngModel )]="searchContact" >
<igx-suffix *ngIf ="search.value.length > 0" (click )="searchContact = null" >
<igx-icon > clear</igx-icon >
</igx-suffix >
</igx-input-group >
<div class ="list-sample" >
<igx-list >
<igx-list-item [isHeader ]="true" > Contacts</igx-list-item >
<igx-list-item igxRipple igxRippleTarget =".igx-list__item-content" #item
*ngFor ="let contact of contacts | igxFilter: filterContacts;" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<span igxListLineTitle > {{ contact.name }}</span >
<span igxListLineSubTitle > {{ contact.phone }}</span >
<igx-icon igxListAction [style.color ]="contact.isFavorite ? 'orange' : 'lightgray'" igxRipple ="pink"
[igxRippleCentered ]="true" (click )="toggleFavorite(contact, $event)"
(mousedown )="mousedown($event)" > star</igx-icon >
</igx-list-item >
</igx-list >
</div >
html コピー :host {
display : block;
padding : 16px ;
}
.list-sample {
box-shadow : 0px 1px 3px 0px rgba(0 , 0 , 0 , 0.2 ),
0px 1px 1px 0px rgba(0 , 0 , 0 , 0.14 ),
0px 2px 1px -1px rgba(0 , 0 , 0 , 0.12 );
}
.density-chooser {
margin-bottom : 16px ;
}
igx-icon {
cursor : pointer;
position : relative;
}
.search {
margin-bottom : 16px ;
}
scss コピー
List Items Panning
Ahora que tenemos una lista Angular tan hermosa con contactos y sus números de teléfono, ¿por qué no implementamos la capacidad de llamar a un contacto? IgxList
tiene la solución perfecta para esto: panorámica de elementos de la lista. Para ello hay que implementar los siguientes pasos:
Habilite la panorámica usando las propiedades allowLeftPanning
y/o allowRightPanning
Definir plantillas para la panorámica izquierda y/o derecha
Manejar los eventos de panorámica del elemento de la lista y realizar la acción deseada
El siguiente ejemplo demuestra cómo manejar la panorámica izquierda y derecha. El controlador de eventos para la panorámica derecha muestra un mensaje de brindis. El controlador de eventos para la panorámica izquierda elimina un elemento de IgxList
.
Tenga en cuenta que la eliminación de elementos de la lista es una tarea de la aplicación. La propia IgxList
no puede eliminar elementos de la fuente de datos porque IgxList
no tiene referencia a la fuente de datos.
Aquí está el código HTML del ejemplo:
<igx-list [allowLeftPanning ]="true" [allowRightPanning ]="true"
(leftPan )="leftPanPerformed($event)" (rightPan )="rightPanPerformed($event)" >
<ng-template igxListItemLeftPanning >
<div class ="listItemLeftPanningStyle" >
<igx-icon [color ]="white" style ="margin-left:10px" > delete</igx-icon >Delete
</div >
</ng-template >
<ng-template igxListItemRightPanning >
<div class ="listItemRightPanningStyle" >
<igx-icon [color ]="white" style ="margin-right:10px" > call</igx-icon >Dial
</div >
</ng-template >
<igx-list-item isHeader ="true" > Contacts</igx-list-item >
<igx-list-item #item *ngFor ="let contact of contacts" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<h4 igxListLineTitle > {{ contact.name }}</h4 >
<p igxListLineSubTitle class ="phone" > {{ contact.phone }}</p >
<igx-icon igxListAction [color ]="contact.isFavorite ? 'orange' : 'lightgray'" (click )="toggleFavorite(item)" > star</igx-icon >
</igx-list-item >
</igx-list >
<igx-toast #toast > </igx-toast >
html
El ejemplo anterior utiliza algunos estilos CSS que se pueden encontrar aquí:
igx-icon {
cursor : pointer;
user-select: none;
}
.listItemLeftPanningStyle {
display : flex;
flex-direction : row-reverse;
background-color :orange;
color : white;
width : 100% ;
padding-right : 10px ;
align-items : center;
}
.listItemRightPanningStyle {
display : flex;
flex-direction : row;
background-color :limegreen;
color : white;
width : 100% ;
padding-left : 10px ;
align-items : center;
}
css
Y finalmente aquí está el código mecanografiado que maneja los eventos de panorámica:
...
@ViewChild ('toast' )
public toast: IgxToastComponent;
public rightPanPerformed (args ) {
args.keepItem = true ;
this .toast.message = 'Dialing ' + this .contacts[args.item.index - 1 ].name;
this .toast.open();
}
public leftPanPerformed (args ) {
args.keepItem = false ;
setTimeout ((idx = args.item.index - 1 ) => {
this .toast.message = 'Contact ' + this .contacts[idx].name + ' removed.' ;
this .toast.open();
this .contacts.splice(idx, 1 );
}, 500 );
}
...
typescript
Al realizar una panorámica de los elementos de la lista, hay un umbral que se debe alcanzar para que se emitan los eventos de panorámica. Puede cambiar el umbral utilizando la propiedad panEndTriggeringThreshold
de IgxList
. De forma predeterminada, esta propiedad tiene un valor de 0,5, lo que significa el 50% del ancho del elemento de la lista.
Ahora intente desplazarse por los elementos de la lista usted mismo:
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxAvatarModule,
IgxIconModule,
IgxListModule,
IgxRippleModule,
IgxSliderModule,
IgxToastModule,
IgxButtonModule
} from "igniteui-angular" ;
import { ListSample7Component } from "./list-sample-7/list-sample-7.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample7Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxAvatarModule,
IgxIconModule,
IgxListModule,
IgxRippleModule,
IgxSliderModule,
IgxToastModule,
IgxButtonModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component, OnInit, ViewChild } from '@angular/core' ;
import { IgxListComponent, IgxToastComponent } from 'igniteui-angular' ;
@Component ({
selector : 'app-contact-list2' ,
styleUrls : ['./list-sample-7.component.scss' ],
templateUrl : './list-sample-7.component.html'
})
export class ListSample7Component implements OnInit {
@ViewChild ('toast' , { static : true })
public toast: IgxToastComponent;
@ViewChild ('mainIgxList' , { static : true })
public list: IgxListComponent;
public contacts;
private dataSource = [{
isFavorite : false ,
name : 'Terrance Orta' ,
phone : '770-504-2217' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/27.jpg'
}, {
isFavorite : true ,
name : 'Richard Mahoney' ,
phone : '423-676-2869' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/1.jpg'
}, {
isFavorite : false ,
name : 'Donna Price' ,
phone : '859-496-2817' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/50.jpg'
}, {
isFavorite : false ,
name : 'Lisa Landers' ,
phone : '901-747-3428' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/3.jpg'
}, {
isFavorite : true ,
name : 'Dorothy H. Spencer' ,
phone : '573-394-9254' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/67.jpg'
}
];
constructor ( ) {
}
public ngOnInit ( ) {
this .contacts = Object .assign([], this .dataSource);
}
public toggleFavorite (contact: any , event: Event ) {
event.stopPropagation();
contact.isFavorite = !contact.isFavorite;
}
public rightPanPerformed (args ) {
args.keepItem = true ;
this .toast.open('Dialing ' + this .contacts[args.item.index - 1 ].name);
}
public leftPanPerformed (args ) {
args.keepItem = false ;
setTimeout ((idx = args.item.index - 1 ) => {
this .toast.open('Contact ' + this .contacts[idx].name + ' removed.' );
this .contacts.splice(idx, 1 );
}, 500 );
}
public repopulateHandler ( ) {
this .contacts = Object .assign([], this .dataSource);
}
public get panThreshold () {
const result = this .list.panEndTriggeringThreshold;
return Math .round(result * 100 ) + '%' ;
}
public mousedown (event: Event ) {
event.stopPropagation();
}
}
ts コピー <div style ="width:300px; margin-bottom:20px" >
<igx-slider id ="slider" [minValue ]="0.1" [maxValue ]="0.9" [step ]="0.1" [continuous ]="true"
[(ngModel )]="mainIgxList.panEndTriggeringThreshold" > </igx-slider >
<label > Threshold: {{panThreshold}}</label >
</div >
<div class ="list-sample" >
<igx-list [allowLeftPanning ]="true" [allowRightPanning ]="true" #mainIgxList (leftPan )="leftPanPerformed($event)"
(rightPan )="rightPanPerformed($event)" >
<ng-template igxListItemLeftPanning >
<div class ="listItemLeftPanningStyle" >
<igx-icon > delete</igx-icon >Delete
</div >
</ng-template >
<ng-template igxListItemRightPanning >
<div class ="listItemRightPanningStyle" >
<igx-icon > call</igx-icon >Dial
</div >
</ng-template >
<igx-list-item [isHeader ]="true" > Contacts</igx-list-item >
<igx-list-item #item *ngFor ="let contact of contacts" igxRipple ="pink"
igxRippleTarget =".igx-list__item-content" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<span igxListLineTitle > {{ contact.name }}</span >
<span igxListLineSubTitle > {{ contact.phone }}</span >
<igx-icon igxListAction [style.color ]="contact.isFavorite ? 'orange' : 'lightgray'" igxRipple ="pink"
[igxRippleCentered ]="true" (click )="toggleFavorite(contact, $event)"
(mousedown )="mousedown($event)" > star</igx-icon >
</igx-list-item >
</igx-list >
<igx-toast #toast > </igx-toast >
</div >
<button igxButton ="contained" (click )="repopulateHandler()" style ="margin-top:20px" > Repopulate IgxList</button >
html コピー :host {
display : block;
padding : 16px ;
}
.list-sample {
box-shadow : 0px 1px 3px 0px rgba(0 , 0 , 0 , 0.2 ),
0px 1px 1px 0px rgba(0 , 0 , 0 , 0.14 ),
0px 2px 1px -1px rgba(0 , 0 , 0 , 0.12 );
}
igx-icon {
cursor : pointer;
position : relative;
}
.listItemLeftPanningStyle {
display : flex;
flex-direction : row-reverse;
background-color :orange;
color : white;
width : 100% ;
padding-right : 10px ;
align-items : center;
}
.listItemRightPanningStyle {
display : flex;
flex-direction : row;
background-color :limegreen;
color : white;
width : 100% ;
padding-left : 10px ;
align-items : center;
}
scss コピー
Angular filter list
Nuestra lista se ve bien, pero ¿no sería aún mejor si pudiéramos buscar contactos por nombre? Esto lo podemos lograr fácilmente utilizando nuestro tubo filtrante. Hagámoslo.
Primero agreguemos un campo de entrada en la parte superior de nuestra plantilla de componente Angular y vincúlelo a una propiedad en nuestro componente llamada searchContact :
<igx-input-group type ="search" class ="search" >
<igx-prefix >
<igx-icon > search</igx-icon >
</igx-prefix >
<input #search igxInput placeholder ="Search Contacts" [(ngModel )]="searchContact" >
<igx-suffix *ngIf ="search.value.length > 0" (click )="searchContact = null" >
<igx-icon > clear</igx-icon >
</igx-suffix >
</igx-input-group >
html
Es hora de importar IgxFilterModule
e IgxInputGroupModule
en nuestro archivo app.module.ts e IgxFilterOptions
en nuestro componente de contactos:
...
import { IgxFilterModule, IgxInputGroupModule } from 'igniteui-angular' ;
@NgModule ({
imports : [..., IgxFilterModule, IgxInputGroupModule]
})
...
import { IgxFilterOptions } from 'igniteui-angular' ;
@Component ({...})
export class ContactListComponent {
public searchContact: string ;
...
get filterContacts (): IgxFilterOptions {
const fo = new IgxFilterOptions();
fo.key = 'name' ;
fo.inputValue = this .searchContact;
return fo;
}
}
typescript
Después de importar IgxFilterOptions
, debemos registrar un nuevo método getter que devolverá las opciones de filtrado que utilizará la canalización cada vez que se actualice la propiedad searchContact
. Para que el filtro funcione necesitamos registrar una key
para filtrar el objeto de contacto. En nuestro caso ese sería el name
de cada contacto. La segunda propiedad que debe registrarse en el objeto IgxFilterOptions
es el valor que debemos comparar al comparar nuestro nombre de contacto. Esta sería la propiedad searchContact
que vinculamos al campo de entrada encima de nuestra lista de contactos.
Finalmente, debemos aplicar el tubo de filtrado a los datos de nuestros contactos antes de poder usarlo. Entonces en nuestra plantilla simplemente agregamos:
<igx-list-item *ngFor ="let contact of contacts | igxFilter: filterContacts; let i = index" >
...
</igx-list-item >
html
List Item Selection
Como probablemente ya habrás notado, los elementos de la lista no proporcionan estados de selección. Sin embargo, si su aplicación requiere que su lista realice un seguimiento de qué elemento se selecciona, le brindamos un ejemplo de cómo se puede lograr esto. Todo lo que necesita hacer es realizar un seguimiento del estado en algún lugar de su componente o en los datos a los que está vinculada la lista.
Aquí hay un ejemplo, en el que aplicamos un color de fondo a la lista de acuerdo con el color secundario 500 del tema, según el seguimiento del estado proveniente de los datos a los que está vinculada la lista:
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxAvatarModule,
IgxFilterModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule
} from "igniteui-angular" ;
import { ListItemSelectionComponent } from "./list-item-selection/list-item-selection.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListItemSelectionComponent
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxAvatarModule,
IgxFilterModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component } from '@angular/core' ;
import { IgxFilterOptions } from 'igniteui-angular' ;
@Component ({
selector : 'app-list-item-selection' ,
templateUrl : './list-item-selection.component.html' ,
styleUrls : ['./list-item-selection.component.scss' ]
})
export class ListItemSelectionComponent {
public searchContact: string ;
public contacts = [
{
isFavorite : false ,
name : 'Terrance Orta' ,
phone : '770-504-2217' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/27.jpg' ,
selected : false
},
{
isFavorite : true ,
name : 'Richard Mahoney' ,
phone : '423-676-2869' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/1.jpg' ,
selected : false
},
{
isFavorite : false ,
name : 'Donna Price' ,
phone : '859-496-2817' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/50.jpg' ,
selected : false
},
{
isFavorite : false ,
name : 'Lisa Landers' ,
phone : '901-747-3428' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/3.jpg' ,
selected : false
},
{
isFavorite : true ,
name : 'Dorothy H. Spencer' ,
phone : '573-394-9254' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/67.jpg' ,
selected : false
}
];
public toggleFavorite (contact: any , event: Event ) {
event.stopPropagation();
contact.isFavorite = !contact.isFavorite;
}
public selectItem (item ) {
if (!item.selected) {
this .contacts.forEach(c => c.selected = false );
item.selected = true ;
}
}
get filterContacts () {
const fo = new IgxFilterOptions();
fo.key = 'name' ;
fo.inputValue = this .searchContact;
return fo;
}
public mousedown (event: Event ) {
event.stopPropagation();
}
}
ts コピー <igx-input-group type ="search" class ="search" >
<igx-prefix >
<igx-icon > search</igx-icon >
</igx-prefix >
<input #search igxInput placeholder ="Search Contacts" [(ngModel )]="searchContact" >
<igx-suffix *ngIf ="search.value.length > 0" (click )="searchContact = null" >
<igx-icon > clear</igx-icon >
</igx-suffix >
</igx-input-group >
<div class ="list-sample" >
<igx-list >
<igx-list-item [isHeader ]="true" > Contacts</igx-list-item >
<igx-list-item [ngClass ]="contact.selected ? 'selected' : ''" (click )="selectItem(contact)"
*ngFor ="let contact of contacts | igxFilter: filterContacts;" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<span igxListLineTitle > {{ contact.name }}</span >
<span igxListLineSubTitle > {{ contact.phone }}</span >
<igx-icon igxListAction [style.color ]="contact.isFavorite ? 'orange' : 'lightgray'" igxRipple ="pink"
[igxRippleCentered ]="true" (click )="toggleFavorite(contact, $event)"
(mousedown )="mousedown($event)" > star</igx-icon >
</igx-list-item >
</igx-list >
</div >
html コピー :host {
display : block;
padding : 16px ;
.selected {
background-color : var(--ig-secondary-500 )
}
.list-sample {
box-shadow: 0px 1px 3px 0px rgba(0 , 0 , 0 , 0.2 ),
0px 1px 1px 0px rgba(0 , 0 , 0 , 0.14 ),
0px 2px 1px -1px rgba(0 , 0 , 0 , 0.12 );
}
igx-icon {
cursor : pointer;
position : relative;
}
.search {
margin-bottom : 16px ;
}
}
scss コピー
Lo que estamos haciendo es agregar una propiedad selected
adicional a cada miembro de datos, cuyo valor predeterminado es false
. Al hacer clic en el elemento de la lista, restablecemos todas las propiedades selected
en la recopilación de datos y configuramos la correspondiente al elemento en el que se hizo clic en true
. Según la propiedad seleccionada, aplicamos una clase CSS al elemento de la lista que le proporciona el fondo seleccionado.
<igx-list >
<igx-list-item isHeader ="true" > Contacts</igx-list-item >
<igx-list-item [ngClass ]="contact.selected ? 'selected' : ''"
(click )="selectItem(contact)"
*ngFor ="let contact of contacts | igxFilter: filterContacts;" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<span igxListLineTitle > {{ contact.name }}</span >
<span igxListLineSubTitle > {{ contact.phone }}</span >
<igx-icon igxListAction [style.color ]="contact.isFavorite ? 'orange' : 'lightgray'" (click )="toggleFavorite(contact, $event)" > star</igx-icon >
</igx-list-item >
</igx-list >
html
public selectItem (item ) {
if (!item.selected) {
this .contacts.forEach(c => c.selected = false );
item.selected = true ;
}
}
typescript
.selected {
background-color : hsla(var(--igx-secondary-500 ))
}
scss
Chat Component
En el ejemplo siguiente se muestra cómo crear un componente de chat simple mediante IgxList .
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxAvatarModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule
} from "igniteui-angular" ;
import { ListChatSampleComponent } from "./list-chat-sample/list-chat-sample.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListChatSampleComponent
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxAvatarModule,
IgxIconModule,
IgxListModule,
IgxInputGroupModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import {
AfterViewInit,
Component,
ElementRef,
TemplateRef,
ViewChild,
ViewEncapsulation
} from '@angular/core' ;
import { ContactsService } from './services/contacts.service' ;
import { IMessage, MessagesService } from './services/messages.service' ;
@Component ({
encapsulation : ViewEncapsulation.None,
selector : 'app-list-chat-sample' ,
styleUrls : ['./list-chat-sample.component.scss' ],
templateUrl : './list-chat-sample.component.html'
})
export class ListChatSampleComponent implements AfterViewInit {
@ViewChild ('form' , { static : true })
public form: ElementRef;
@ViewChild ('myMessage' , { static : true })
public myMessageTemplate: TemplateRef<any >;
@ViewChild ('othersMessage' , { static : true })
public othersMessageTemplate: TemplateRef<any >;
public message: string ;
private myId = 4 ;
constructor (
public messagesService: MessagesService,
public contactsService: ContactsService
) { }
public getMessageTemplate(message: IMessage): TemplateRef<any > {
if (message.authorId === this .myId) {
return this .myMessageTemplate;
}
return this .othersMessageTemplate;
}
public isFirstMessage(messageIndex: number ): boolean {
if (messageIndex === 0 ) {
return true ;
}
const messages = this .messagesService.getMessages();
if (messageIndex >= messages.length) {
return false ;
}
const currentMessage = messages[messageIndex];
const previousMessage = messages[messageIndex - 1 ];
return currentMessage.authorId !== previousMessage.authorId;
}
public onMessageKeypress (event ) {
if (event.key === 'Enter' ) {
this .sendMessage();
}
}
public onSendButtonClick ( ) {
this .sendMessage();
}
private sendMessage ( ) {
this .addMessage(this .message);
this .message = null ;
}
private addMessage (message: string ) {
if (message) {
const messageInstance: IMessage = {
authorId : this .myId,
message,
timestamp : new Date (Date .now())
};
this .messagesService.addMessage(messageInstance);
}
}
public ngAfterViewInit ( ) {
this .scrollToBottom();
}
private scrollToBottom(): void {
const form = this .form.nativeElement;
form.scrollTop = form.scrollHeight;
}
}
ts コピー <form #form class ="sample-form" >
<igx-list #list >
<ng-template
#othersMessage
let-message ="message"
let-contact ="contact"
let-messageIndex ="index"
>
<igx-list-item class ="contact" *ngIf ="isFirstMessage(messageIndex)" >
<section class ="contact__panel" >
<igx-avatar
[src ]="contact.photo"
shape ="circle"
> </igx-avatar >
<header class ="message__info" >
<h6 > {{ contact.name }}</h6 >
<span >
{{ message.timestamp | date: "shortTime" }}
</span >
</header >
</section >
</igx-list-item >
<igx-list-item >
<div
[ngClass ]="{
message: true,
'other-message': true,
'other-message--first': isFirstMessage(messageIndex)
}"
>
<span > {{ message.message }}</span >
</div >
</igx-list-item >
</ng-template >
<ng-template #myMessage let-message ="message" let-messageIndex ="index" >
<igx-list-item class ="contact" *ngIf ="isFirstMessage(messageIndex)" >
<header class ="own-message message__info" >
<h6 > You</h6 >
<span class ="message__info" >
{{ message.timestamp | date: "shortTime" }}
</span >
</header >
</igx-list-item >
<igx-list-item >
<div
[ngClass ]="{
message: true,
'own-message': true,
'own-message--first': isFirstMessage(messageIndex)
}"
>
<span >
{{ message.message }}
</span >
</div >
</igx-list-item >
</ng-template >
<ng-container
*ngFor ="let message of messagesService.getMessages(); index as i"
>
<ng-container
*ngTemplateOutlet ="
getMessageTemplate(message);
context: {
message: message,
contact: contactsService.getContact(message.authorId),
index: i
}
"
>
</ng-container >
</ng-container >
</igx-list >
<div class ="overflow-anchor" > </div >
<div class ="massage-field" >
<igx-input-group type ="box" >
<input
#newMessage
igxInput
name ="newMessage"
placeholder ="Send message"
autocomplete ="off"
[(ngModel )]="message"
(keypress )="onMessageKeypress($event)"
/>
<button
igxSuffix
igxIconButton ="flat"
(click )="onSendButtonClick()"
>
<igx-icon name ="send" family ="material" > </igx-icon >
</button >
</igx-input-group >
</div >
</form >
html コピー @use "igniteui-angular/theming" as *;
igx-avatar {
--ig-size: var(--ig-size-small);
}
igx-list {
--ig-spacing-block-small: 0 ;
--ig-spacing-block-medium: 0 ;
--ig-spacing-block-large: 0 ;
--item-background : transparent;
--border-color : transparent;
--item-background -hover: transparent;
--item-background -active: transparent;
gap: rem(4px );
}
.sample-form {
overflow-y : scroll;
overflow-x : auto;
max-width : rem(400px );
height : rem(580px );
background : color(null, surface, 500 );
box-shadow : var(--ig-elevation-12 );
margin : rem(24px ) auto;
border-radius : rem(4px );
* {
overflow -anchor: none;
}
}
.massage-field {
position : sticky;
bottom : 0 ;
padding -block: rem(12px );
padding -inline: rem(16px );
background : color(null, surface, 500 );
}
.overflow-anchor {
height : 1px ;
overflow -anchor: auto;
}
.contact {
margin -block: rem(24px ) rem(8px );
&__panel {
display : flex;
align-items : center;
gap: rem(8px );
}
&__panel {
display : flex;
align-items : center;
}
&:active {
background : transparent;
}
}
.message {
@include type-style("body-2" );
display : flex;
align-items : center;
min-height : rem(32px );
border-radius : rem(4px );
padding -inline: rem(16px );
&__info {
h6 {
@include type-style("body-1" );
font-weight : 600 ;
margin : initial;
line-height : 1 ;
}
span {
@include type-style("caption" );
}
}
}
.own-message {
margin -inline-start: auto;
background-color : color(null, gray, 200 );
color : contrast-color(null, gray, 200 );
&--first {
border-top-right-radius : 0 ;
}
&.message__info {
background : transparent;
color : color(null, gray, 700 );
text-align : end;
}
&:active {
background-color : inherit;
}
}
.other-message {
background-color : color(null, primary, 800 );
color : contrast-color(null, primary, 800 );
&--first {
border-top-left-radius : 0 ;
}
&:active {
background-color : color(null, primary, 900 );
color : contrast-color(null, primary, 900 );
}
}
scss コピー
Applying theme to the list component
Veamos cómo podemos cambiar el fondo de nuestra lista. Primero necesitamos importar index.scss al archivo .scss de nuestro componente.
@use "igniteui-angular/theming" as *;
scss
Siguiendo el enfoque más simple, creamos un nuevo tema que extiende el list-theme
y acepta el $background
parámetro.
$my-list-theme : list-theme(
$background : #0568ab
);
scss
Eche un vistazo a la list-theme
sección para obtener una lista completa de los parámetros disponibles para diseñar la lista.
El último paso es incluir los temas recién creados.
@include css-vars($my-list-theme );
scss
El resultado es el siguiente:
import { NgModule } from "@angular/core" ;
import { FormsModule } from "@angular/forms" ;
import { BrowserModule } from "@angular/platform-browser" ;
import { BrowserAnimationsModule } from "@angular/platform-browser/animations" ;
import { AppComponent } from "./app.component" ;
import {
IgxToastModule,
IgxListModule,
IgxIconModule,
IgxAvatarModule
} from "igniteui-angular" ;
import { ListSample8Component } from "./list-sample-8/list-sample-8.component" ;
@NgModule ({
bootstrap : [AppComponent],
declarations : [
AppComponent,
ListSample8Component
],
imports : [
BrowserModule,
BrowserAnimationsModule,
FormsModule,
IgxToastModule,
IgxListModule,
IgxIconModule,
IgxAvatarModule
],
providers : [],
schemas : []
})
export class AppModule {}
ts コピー import { Component, OnInit, ViewChild } from '@angular/core' ;
import { IgxListComponent, IgxToastComponent } from 'igniteui-angular' ;
@Component ({
selector : 'app-list-8' ,
styleUrls : ['./list-sample-8.component.scss' ],
templateUrl : './list-sample-8.component.html'
})
export class ListSample8Component implements OnInit {
@ViewChild ('toast' , { static : true })
public toast: IgxToastComponent;
@ViewChild ('mainIgxList' , { static : true })
public list: IgxListComponent;
public contacts;
private dataSource = [{
isFavorite : false ,
name : 'Terrance Orta' ,
phone : '770-504-2217' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/27.jpg'
}, {
isFavorite : true ,
name : 'Richard Mahoney' ,
phone : '423-676-2869' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/men/1.jpg'
}, {
isFavorite : false ,
name : 'Donna Price' ,
phone : '859-496-2817' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/50.jpg'
}, {
isFavorite : false ,
name : 'Lisa Landers' ,
phone : '901-747-3428' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/3.jpg'
}, {
isFavorite : true ,
name : 'Dorothy H. Spencer' ,
phone : '573-394-9254' ,
photo : 'https://www.infragistics.com/angular-demos-lob/assets/images/women/67.jpg'
}
];
constructor ( ) {
}
public ngOnInit ( ) {
this .contacts = Object .assign([], this .dataSource);
}
public toggleFavorite (contact: any , event: Event ) {
event.stopPropagation();
contact.isFavorite = !contact.isFavorite;
}
public mousedown (event: Event ) {
event.stopPropagation();
}
}
ts コピー <div class ="list-sample" >
<igx-list >
<igx-list-item [isHeader ]="true" > Contacts</igx-list-item >
<igx-list-item #item *ngFor ="let contact of contacts" >
<igx-avatar igxListThumbnail [src ]="contact.photo" shape ="circle" > </igx-avatar >
<span igxListLineTitle > {{ contact.name }}</span >
<span igxListLineSubTitle > {{ contact.phone }}</span >
<igx-icon igxListAction [style.color ]="contact.isFavorite ? 'orange' : 'lightgray'" igxRipple ="white"
[igxRippleCentered ]="true" (click )="toggleFavorite(contact, $event)"
(mousedown )="mousedown($event)" > star</igx-icon >
</igx-list-item >
</igx-list >
</div >
html コピー @use '../../variables' as *;
:host ::ng-deep {
$my-list-theme : list-theme(
$background : #0568ab
);
@include css-vars($my-list-theme );
}
:host {
display : block;
padding : 16px ;
}
.list-sample {
box-shadow : elevation(2 );
}
igx-icon {
cursor : pointer;
position : relative;
}
scss コピー
Para obtener una lista completa de los parámetros que puede cambiar para el componente de lista, consulte: Estilos de componentes IgxList
API References
En este artículo cubrimos mucho terreno con el componente de lista Angular. Creamos una lista de elementos de contacto. Se utilizó alguna Ignite UI for Angular dentro de los elementos de nuestra lista, como avatares e íconos. Creé un diseño de elemento personalizado y le di estilo. Finalmente, agregamos filtrado de listas. El componente de lista tiene algunas API más para explorar, que se enumeran a continuación.
Componentes Angular adicionales que se utilizaron:
Theming Dependencies
Additional Resources
Nuestra comunidad es activa y siempre da la bienvenida a nuevas ideas.