@Component({
...
template: '<p #bio></p>'
})
export class UserDetailsComponent {
@ViewChild('bio') bio;
}
<p>
con la variabile di riferimento del modello bio nella visualizzazione del modello del componente.<p>
di cui viene eseguito il rendering come figlio della visualizzazione padre che utilizza questo componente.<p>
nel modello supporta la proiezione del contenuto.<p>
visibile nel rendering finale. Se il #bio è stato utilizzato nel modello e il @ViewChild non è stato utilizzato nella classe, Angular nasconderà automaticamente il valore <p>
che ha #bio su di esso.DigitalOcean - viewchild-access-component
Angular.io - Gruppi di moduli reattivi
paramMap
E la queryParamMap
sul ActivatedRoute
classe?<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 - Invio di dati al server
@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 - Metadati dei componenti
<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 - Direttive strutturali
Angular.io - Stili dei componenti
@Component({
selector: 'app-title-card',
template: '',
})
class TitleCardComponent {
title = 'User Data';
}
title
[title]
Angular.io - Interpolazione di stringhe o Interpolazione di testo
Angular.io - Visualizzazione di un valore di controllo from
<a>
tag al routing?@Component({
selector: 'app-shopping-cart',
. . .
})
export class ShoppingCartComponent {
@Output() itemTotalChanged = new EventEmitter();
}
itemTotalChanged
campo di classe pubblico.itemTotalChanged
campo di classe, in questo modo: <app-shopping-cart [itemTotalChanged]="newTotal"></app-shopping-cart>
.itemTotalChanged
campo di classe, in questo modo: <app-shopping-cart (itemTotalChanged)="logNewTotal($event)"></app-shopping-cart>
.Angular.io - Invio di dati al componente padre
<div *ngIf="isVisible">Active</div>
<div [hidden]="!isVisible">Active</div>
ngIf
è una scorciatoia per l’altro esempio. Quando Angular elabora tale direttiva, scrive un elemento div nel DOM con la proprietà nascosta.ngIf
non esegue il rendering del div nel DOM se l’espressione è false. Le hidden
l’utilizzo della proprietà nasconde il contenuto div nel riquadro di visualizzazione del browser, ma il div è ancora nel DOM.ngIf
è valido, ma l’uso del hidden
è errata e genererà un errore.<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 - Invia il modulo con ngSubmit
Angular.io - ng genera opzioni
@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 - Interpolazione delle stringhe
Angular.io - Ganci per il ciclo di vita
<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 - Percorsi parametrizzati
@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 -Mostra e nascondi errore di convalida
<h1 #headerText>User List</h1>
<h1>
elementoPluralsight - Variabile di riferimento del modello
[{ provide: FormattedLogger, useClass: Logger }][{ provide: FormattedLogger, useExisting: Logger }];
Angular.io - Provider di dipendenze
{
path: 'customers',
component: CustomerListComponent,
data: { accountSection: true }
}
ngIf
direttiva strutturale modificare il DOM renderizzato in base a questa sintassi del modello?@Component({
selector: 'app-product',
template: '<div *ngIf="product"></div>',
})
export class ProductComponent {
@Input() product;
}
<div>
funge da segnaposto. Se il campo della classe di prodotto è “truthy”, l’opzione <div>
verrà sostituito solo dal product.name
valore; in caso contrario, non verrà eseguito il rendering di nulla.<div>
verrà sempre renderizzato e, se il campo di prodotto è “veritiero”, il <div>
conterrà l’elemento product.name
valore; In caso contrario, verrà eseguito il rendering del comando <div>
elemento senza valore.<div>
con il valore del product.name
campo. Se non è “veritiero”, il DOM renderizzato non conterrà il <div>
elemento.@NgModule({
declarations: [AppComponent],
imports: [BrowserModule],
bootstrap: [AppComponent],
})
export class AppModule {}
platformBrowserDynamic().bootstrapModule(AppModule);
Angular.io - Il NgModule di base
{
path: ':id',
component: UserComponent,
resolve: {
user: UserResolverService
}
}
@Component({
. . .
template: '<ng-content></ng-content›'
})
export class TabsListComponent {
@ContentChildren(TabComponent) tabs;
}
fixture.detectChanges()
chiamare in questo unit test?TestBed.configureTestingModule({
declarations: [UserCardComponent],
});
let fixture = TestBed.createComponent(UserCardComponent);
fixture.detectChanges();
expect(fixture.nativeElement.querySelector('h1').textContent).toContain(
fixture.componentInstance.title,
);
Router.navigate
quando goToUser viene passato il valore 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 - Dependency Injection In Azione
export class SettingsService {
constructor(private httpClient: HttpClient) { }
...
getSettings()
{
return this.httpClient.get<Settings>(this.settingsUrl)
.pipe(
retry(3)
);
}}
getSettings
eseguirà la query get. L’operatore di ripetizione dei tentativi viene utilizzato per indicare alla chiamata di pipe di riprovare la query get tre volte.Httpclient.get
chiamare.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
richiesta?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
è stato registrato nei provider per l’applicazione, quale risposta descrive meglio cosa succede in base al costruttore di questo componente? @Component({
...
})
export class OrderHistoryComponent {
constructor(private dataService: DataService) {}
...
}
OrderHistoryComponent
avrà la propria versione di un DataService
e che non dovrebbe mai utilizzare istanze esistenti. Le DataService
dovrebbe essere istanziato all’interno della classe come campo privato affinché questo codice sia completo e funzionante.OrderHistoryComponent
, l’iniettore fornirà un’istanza di un DataService
al primo argomento del costruttore del componente. Il costruttore dataService
verrà utilizzato per impostare un campo di istanza privata con lo stesso nome sull’istanza.dataService
che può essere utilizzato per associare un DataService
istanza a.Angular.io - Iniezione di dipendenze
ngIf
direttiva per implementare un altro caso che visualizzerà il testo “L’utente non è attivo”:<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 - Moduli di caricamento pigro
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
per username
viene configurato per escludere tre validatori dai validatori che è consentito utilizzare.FormControl
per username
si sta configurando per consentire l’utilizzo di tre possibili validatori: required, maxLength
e uno personalizzato denominato unique
. Per abilitarli validators
, una direttiva di convalida dovrebbe essere inserita nei campi modulo nel markup.FormControl
per username
si sta configurando con tre validatori: il required
e minLength
validatori che provengono da Angular e una funzione di convalida personalizzata denominata unique
che verifica la presenza del valore non uguale alla stringa admin
.Angular.io - Convalida del modulo
@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
proprietà element title?<h1 [title]="userName">Current user is </h1>
async
pipe facendo in questo esempio?@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
affermazione.ngFor
per supportare più elenchi di utenti contemporaneamente.HttpClient.get
e il wrapping del valore restituito in modo che possa essere ripetuto nella finestra di dialogo ngFor
.users
da eseguire il rendering contemporaneamente al 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>
Come rilevare quando un valore @Input() cambia in 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] {( ‘del testo lungo’ | troncare:10 }) |
[ ] {( ‘some long text’ | truncate:10:true }) |
[ ] {( ‘un po’ di testo lungo’ | troncare }) |
[ricontrolla le risposte]
[ricontrolla le risposte]
<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>
[ricontrolla le risposte]
export interface AppSettings {
title: string;
version: number;
}
[ricontrolla le risposte]
Unit test angolari - ricontrollare le risposte
CanActivate vs Canload CanActivate impedisce l’accesso sui percorsi, CanLoad impedisce il caricamento lento.
{
path: 'document',
component: DocumentComponent,
outlet: 'document-box'
}
Uscita angolare - ricontrolla la risposta