@Component({
...
template: '<p #bio></p>'
})
export class UserDetailsComponent {
@ViewChild('bio') bio;
}
<p>
que tiene la variable de referencia de plantilla bio en la vista de plantilla del componente.<p>
se representará como un elemento secundario de la vista principal que utiliza este componente.<p>
en la plantilla admite la proyección de contenido.<p>
visible en el renderizado final. Si se utilizó el #bio en la plantilla y no se utilizó el @ViewChild en la clase, Angular ocultaría automáticamente el <p>
etiqueta que tiene #bio en ella.DigitalOcean - viewchild-access-component
Angular.io - Grupos de formularios reactivos
paramMap
y el queryParamMap
en el ActivatedRoute
¿clase?<h2>Names</h2>
<div *ngFor="let user of users | async"></div>
<h2>Ages</h2>
<div *ngFor="let user of users | async"></div>
<h2>Genders</h2>
<div *ngFor="let user of users | async"></div>
export class OrderService {
constructor(private httpClient: HttpClient) {}
addOrder(order: Order) {
// Missing line
}
}
Angular.io - Envío de datos al servidor
@Component({
selector: 'app-user-card',
. . .
})
<div app-user-card></div>
.<app-user-card></app-user-card>
.<app-user-card></app-user-card>
.<user-card></user-card>
.Angular.io - Metadatos de componentes
<ul>
<li [ngFor]="let productName of productNames"></li>
</ul>
<ul>
<li ngFor="let productName of productNames"></li>
</ul>
<ul>
<li *ngFor="let productName of productNames"></li>
</ul>
<ul>
<? for productName in productNames { ?>
<li></li>
<? } ?>
</ul>
Angular.io- Directivas estructurales
Angular.io - Estilos de componentes
@Component({
selector: 'app-title-card',
template: '',
})
class TitleCardComponent {
title = 'User Data';
}
title
[title]
Angular.io - Interpolación de cadenas o Interpolación de texto
Angular.io: visualización de un valor de control de origen
<a>
etiqueta a enrutamiento?@Component({
selector: 'app-shopping-cart',
. . .
})
export class ShoppingCartComponent {
@Output() itemTotalChanged = new EventEmitter();
}
itemTotalChanged
clase de campo público.itemTotalChanged
campo de clase, así: <app-shopping-cart [itemTotalChanged]="newTotal"></app-shopping-cart>
.itemTotalChanged
campo de clase, así: <app-shopping-cart (itemTotalChanged)="logNewTotal($event)"></app-shopping-cart>
.Angular.io - Envío de datos al componente primario
<div *ngIf="isVisible">Active</div>
<div [hidden]="!isVisible">Active</div>
ngIf
es la abreviatura del otro ejemplo. Cuando Angular procesa esa directiva, escribe un elemento div en el DOM con la propiedad oculta.ngIf
no representa el div en el DOM si la expresión es false. El hidden
El uso de la propiedad oculta el contenido div en la ventana gráfica del explorador, pero el div todavía está en el DOM.ngIf
es válido, pero el uso de la hidden
la propiedad es incorrecta y generará un error.<form #userForm="ngForm">
<input type="text" ngModel name="firstName" required />
<input type="text" ngModel name="lastName" required />
<button (click)="submit(userForm.value)">Save</button>
</form>
<button (click)="submit(userForm.value)" disable="userForm.invalid">Save</button>
<button (click)="submit(userForm.value)" [disabled]="userForm.invalid">Save</button>
<button (click)="submit(userForm.value)" [ngForm.disabled]="userForm.valid">Save</button>
<button (click)="submit(userForm.value)" *ngIf="userForm.valid">Save</button>
Angular.io - Envíe el formulario con ngSubmit
Angular.io - ng generar opciones
@Component({
selector: 'app-title-card',
template: '<h1 title="User Data"> </h1>',
})
export class TitleCardComponent {
titleText = 'User Data';
}
<h1 data-title="titleText"></h1>
<h1 title="titleText"></h1>
<h1 [title]="titleText"></h1>
<h1 titleText></h1>
Angular.io - Interpolación de cadenas
Angular.io - Ganchos de ciclo de vida
<span>Boss: </span>
{ path: 'user/:id', component: UserDetailComponent }
{ url: 'user/:id', routedComponent: UserDetailComponent }
{ routedPath: 'user/:id', component: UserDetailComponent }
{ destination: new UserDetailComponent(), route: 'user/:id' }
CodeCraft - Rutas parametrizadas
@Directive({
selector: '[appCallout]',
})
export class CalloutDirective {
@HostBinding('style.font-weight') fontWeight = 'normal';
@HostListener('mouseenter')
onMouseEnter() {
this.fontWeight = 'bold';
}
@HostListener('mouseleave')
onMouseLeave() {
this.fontWeight = 'normal';
}
}
<input type="text" ngModel name="firstName" required minlength="4" />
<span *ngIf="">Invalid field data</span>
Angular.io -Mostrar y ocultar error de validación
<h1 #headerText>User List</h1>
<h1>
elementoPluralsight - Variable de referencia de plantilla
[{ provide: FormattedLogger, useClass: Logger }][{ provide: FormattedLogger, useExisting: Logger }];
Angular.io - Proveedores de dependencia
{
path: 'customers',
component: CustomerListComponent,
data: { accountSection: true }
}
ngIf
La directiva estructural cambia el DOM representado en función de esta sintaxis de plantilla?@Component({
selector: 'app-product',
template: '<div *ngIf="product"></div>',
})
export class ProductComponent {
@Input() product;
}
<div>
actúa como marcador de posición. Si el campo de clase de producto es “veraz”, el <div>
será reemplazado por solo el product.name
valor; si no, entonces nada se renderizará.<div>
siempre se representará, y si el campo de producto es “verdadero”, el <div>
contendrá el elemento product.name
valor; De lo contrario, representará el <div>
elemento sin valor en él.<div>
con el valor de la product.name
campo. Si no es “veraz”, el DOM renderizado no contendrá el <div>
elemento.@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
bootstrap: [AppComponent],
})
export class AppModule {}
platformBrowserDynamic().bootstrapModule(AppModule);
Angular.io - El NgModule básico
{
path: ':id',
component: UserComponent,
resolve: {
user: UserResolverService
}
}
@Component({
. . .
template: '<ng-content></ng-content›'
})
export class TabsListComponent {
@ContentChildren(TabComponent) tabs;
}
fixture.detectChanges()
llamar en esta prueba unitaria?TestBed.configureTestingModule({
declarations: [UserCardComponent],
});
let fixture = TestBed.createComponent(UserCardComponent);
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('h1').textContent).toContain(
fixture.componentInstance.title,
);
Router.navigate
cuando a goToUser se le pasa el valor 15?export class ToolsComponent {
constructor(private router: Router) {}
goToUser(id: number) {
this.router.navigate(['user', id]);
}
}
@Directive({
selector: ' [appHighlight] ',
})
export class HighlightDirective {
@HostBinding('class.highlighted') highlight = true;
}
FormArray
FormControl
FormGroup
all of these answers
<form [formGroup]="form"›
<input type="text" formControlName= "username"›
...
</form>
<span *ngIf="username.minLength.invalid"›
Username length is not valid
</span>
<input type="text" formControlName="username" [showMinLength]="true"›
<span *ngIf="form.get('username').getError('minLength') as minLengthError">
Username must be at least characters.
</span>
<input type="text" formControlName="username" #userName="ngModer">
<span *ngIf="userName.errors.minlength"›
Username must be at least characters.
</span>
TestBed.configureTestingModule({
declarations: [UserCardComponent],
});
let fixture = TestBed.createComponent(UserCardComponent);
fixture.componentTemplate
fixture.getComponentHtml()
fixture.nativeElement
fixture.componentInstance.template
@Component({
selector: 'app-card',
template: '<h1>Data Card</h1><ng-content></ng-content>'
})
export class CardComponent { }
@Component({
selector: 'app-bio',
template: '<ng-content></ng-content>.
})
export class BioComponent { }
// markup usage:
<app-card><app-bio>Been around for four years.</app-bio></app-card>
<app-card>
<h1>Data Card</hl>
<app-bio>
Been around for four years.
</app-bio>
</app-card>
<h1>Data Card</h1>
<app-bio>
Been around for four years.
</app-bio>
<app-card>
<h1>Data Card</hl>
<ng-content></ng-content>
<app-bio>
Been around for four years.
<ng-content></ng-content>
</app-bio>
</app-card>
<app-card>
<h1>Data Card</hl>
</app-card>
@Component({
selector: 'app-user-card',
template: '<app-title-card></app-title-card><p>Jenny Smith</p>'
})
@Component({
selector: 'app-title-card',
template: '<h1>User Data</hl>'
})
// usage of user card component in parent component html
<app-user-card></app-user-card>
<app-user-card>
<app-title-card>
<h1>User Data</h1>
</app-title-card>
<p>Jenny Smith</p>
</app-user-card>
<h1>User Data</h1>
<p>Jenny Smith<p>
<app-user-card>
<app-title-card></app-title-card>
</app-user-card>
<div app-user-card>
<h1 app-title-card>User Data</h1>
<p>Jenny Smith</p>
</div>
constructor(@Inject('Logger') private logger) { }
providers: [Logger];
providers: [{ provide: 'Logger', useClass: Logger }];
@Injectable({
providedln: 'root'
})
providers: [{ provide: 'Logger' }];
Angular.io - Inyección de dependencia en acción
export class SettingsService {
constructor(private httpClient: HttpClient) { }
...
getSettings()
{
return this.httpClient.get<Settings>(this.settingsUrl)
.pipe(
retry(3)
);
}}
getSettings
ejecutará la consulta get. El operador de reintento se utiliza para indicar a la llamada de canalización que vuelva a intentar la consulta get tres veces.Httpclient.get
llamar.const spy = jasmine.createSpyObj('DataService', ['getUsersFromApi']);
TestBed.configureTestingModule({
providers: [UserService, { provide: DataService, useValue: spy }],
});
const userService = TestBed.get(UserService);
All other tests be ignored, including tests that assert results against one of these providers and a non-defined provider.
Although it will work when multiple providers in this configuration are asserted against in a single test.
@Directive({
selector: '[appTruncate]'
})
export class TruncateDirective {
. . .
}
// example of desired usage:
<p [appTruncate]="10">Some very long text here</p>
@Input() appTruncate: number;
@Output() appTruncate;
constructor(maxLength: number) { }
Nothing. The directive selector cannot be used to pass in values to the directive.
HttpClient.get
¿pedir?export class OrderService {
constructor(private httpClient: HttpClient) {}
getOrdersByYear(year: number): Observable<Order[]> {
return this.httpClient.get<Order[]>(this.ordersUrl);
}
}
return this.httpClient.get<Order[]>(this.ordersUrl, {'year': year})
return this.httpClient.get<Order[]>(this.ordersUrl, year)
const options = { params: new HttpParams().set('year', year) };
return this.httpClient.get<Order[]>(this.ordersUrl, options);
getOrdersByYear(year: number): Observable<Order[]> {
return this.httpClient.addParam('year', year).get<Order[]>(this.ordersUrl, year);
}
DataService
se ha registrado en los proveedores de la aplicación, ¿qué respuesta describe mejor lo que sucede en función del constructor de este componente? @Component({
...
})
export class OrderHistoryComponent {
constructor(private dataService: DataService) {}
...
}
OrderHistoryComponent
tendrá su propia versión de un DataService
y que nunca debe utilizar ninguna instancia existente. El DataService
necesitaría ser instanciado dentro de la clase como un campo privado para que este código esté completo y funcione.OrderHistoryComponent
, el inyector proporcionará una instancia de un DataService
al primer argumento del constructor de componentes. El constructor dataService
se usará para establecer un campo de instancia privada con el mismo nombre en la instancia.dataService
que se puede utilizar para enlazar un DataService
instancia a.Angular.io - Inyección de dependencia
ngIf
directiva para implementar otro caso que mostrará el texto “El usuario no está activo”:<div *ngIf="userIsActive; else inactive">
Currently active!
</div>
<div #inactive>User is not active.</div>
<div *ngIf="inactive">
User is not active.
</div>
<ng-template #else="inactive">
<div>User is not active.</div>
</ng-template>
<ng-template #inactive>
<div>User is not active.</div>
</ng-template>
{
path: 'users',
lazy: './users/users.module#UsersModule'
}
{
path: 'users',
loadChildren: () => import('./users/users.module').then(m => m.UserModule)
}
{
path: 'users',
loadChildren: './users/users.module#UsersModule'
}
{
path: 'users',
module: UsersModule
}
Angular.io - Módulos de carga diferida
export class UserFormControl implements OnInit {
...
ngOnInit() {
this.form = this.formBuilder.group({
username: this.formBuilder.control('',
[Validators.required, Validators.minLength(5), this.unique]),
)};
}
unique(control: FormControl) {
return control.value !== 'admin' ? null: {notUnique: true};
}
}
FormControl
para username
se está configurando para excluir tres validadores de los validadores que se le permite usar.FormControl
para username
se está configurando para permitir el uso de tres posibles validadores: required, maxLength
, y uno personalizado denominado unique
. Para habilitar estos validators
, sería necesario colocar una directiva de validador en los campos de formulario del marcado.FormControl
para username
se está configurando con tres validadores: el required
y minLength
validadores que provienen de Angular y una función de validación personalizada denominada unique
que comprueba si el valor no es igual a la cadena admin
.Angular.io - Validación de formularios
Blog de la Universidad Angular
@Injectable({
providedIn: 'root'
)}
export class DataService { }
export interface AppSettings {
title: string;
version: number;
}
export const APP_SETTINGS = new InjectionToken<AppSettings>('app.settings');
<form #form="ngForm">
<input type="text" ngModel="firstName" />
<input type="text" ngModel="lastName" />
<button (click)="submit()">Save</button>
</form>
RouterModule.forRoot(
...{
preloadingStrategy: PreloadAllModules,
},
);
userName
al h1
propiedad de título de elemento?<h1 [title]="userName">Current user is </h1>
async
¿Hacer tubería en este ejemplo?@Component({
selector: 'app-users',
template: '<div *ngFor="let user of users | async"></div>',
})
export class UsersComponent implements OnInit {
users;
constructor(private httpClient: HttpClient) {}
ngOnInit(): void {
this.users = this.httpClient.get<{ name: string }>('users');
}
}
ngFor
declaración.ngFor
iteración para admitir varias listas de usuarios al mismo tiempo.HttpClient.get
y desenvolver el valor devuelto para que se pueda iterar en el cuadro ngFor
.users
que se representará simultáneamente en el DOM.@Directive({
selector: '[appTruncate]'
})
export class TruncateDirective{
. . .
}
html <p data-directive="appTruncate">Some long text </p>
html <p appTruncate>Some long text</p>
html <p app-truncate>Some long text</p>
html <app-truncate>Some long text</app-truncate>
¿Cómo detectar cuando un valor @Input() cambia en Angular?
@Pipe({ name: 'truncate' })
export class TruncatePipe implements PipeTransform {
transform(value: string, maxLength: number, showEllipsis: boolean){
const newValue = maxLength ? value.substr(0, maxLength): value;
return showEllipsis ? '${newValue}...` : newValue;
}
}
[x] {( ‘algún texto largo’ | truncar:10 }) |
[ ] {( ‘algún texto largo’ | truncar:10:true }) |
[ ] {( ‘algún texto largo’ | truncar }) |
[vuelva a verificar las respuestas]
[vuelva a verificar las respuestas]
<div *ngIf="location">
<h1></h1>
<p></p>
</div>
<div *ngIf="location">
<h1></h1>
<p></p>
<ng-template *ngIf="location">
<h1></h1>
<p></p>
</ng-template>
<div *ngIf="location" [display]=" ' hidden' ">
<h1></h1>
<p></p>
</div>
<ng-container *ngIf="location">
<h1></h1>
<p></p>
</ng-container>
[volver a comprobar las respuestas]
export interface AppSettings {
title: string;
version: number;
}
[volver a comprobar las respuestas]
Pruebas unitarias angulares - volver a comprobar las respuestas
CanActivate vs Canload CanActivate impide el acceso en las rutas, CanLoad evita la carga diferida.
{
path: 'document',
component: DocumentComponent,
outlet: 'document-box'
}
Salida angular - volver a comprobar la respuesta