如何在 *ngIf 的 else 部分指向其他组件
How to point other components in the else part of *ngIf
随着 的扩展,这是我需要在 *ngIf
的其他部分使用模板的另一种情况
这是我当前的代码,我在每个页面上使用加载微调器直到 API 响应 returns
<ng-container *ngIf="!isLoading; else spinner">
<form [formGroup]="myForm" novalidate (ngSubmit)="submit()" >
// form content
</form>
</ng-container>
<ng-template #spinner>
<div class="fa-3x tc">
<i class="fas fa-spinner fa-spin"></i>
</div>
</ng-template>
这样我们必须在每个页面上编写相同的 #spinner 组件,所以我创建了一个具有相同内容的组件。
import { Component } from '@angular/core';
@Component({
selector: 'app-display-loading',
styles: [`.load__spinner { color: black; text-align: center; font-size: 30px;}`],
template: `
<ng-template>
<div class="load__spinner"> <i class="fas fa-spinner fa-spin"></i></div>
</ng-template>
`,
preserveWhitespaces: true
})
export class DisplayLoadingComponent {
constructor() {
console.log('display loading called');
}
}
现在我的问题是如何在 *ngIf
中使用这个 <app-display-loading>
组件
或者这可能不是正确的方法。请建议如何执行此操作。
您可以使用 ng-template
来做到这一点,例如:
<div *ngIf="test; else otherTest"></div>
<ng-template #otherTest>
<app-display-loading></app-display-loading>
</ng-template>
更新:
如果您正在使用路由,那么这个示例对您很有用:
在您的 AppComponent 中,您可以订阅导航更改
当 NavigationStart
显示您的微调器时,当 NavigationEnd
隐藏微调器时。
AppModule:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { NavbarComponent } from './navigation/navbar/navbar';
import { HomeComponent } from './views/home/home';
import { CategoriesComponent } from './views/categories/categories';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'categories', component: CategoriesComponent }
];
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes)
],
declarations: [
AppComponent,
NavbarComponent,
HomeComponent,
CategoriesComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
AppComponent:
import { Component } from '@angular/core';
import { Router, NavigationStart, Event, NavigationEnd } from '@angular/router';
@Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
timeout;
routerChanged = true;
constructor(private router: Router) {
router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
// Show spinner
this.routerChanged = true;
}
if (event instanceof NavigationEnd) {
// Hide spinner
this.timeout = setTimeout(() => {
clearTimeout(this.timeout);
this.routerChanged = false;
}, 1000);
}
});
}
}
应用组件Html:
<app-navbar></app-navbar>
<router-outlet></router-outlet>
<div class="spinner" *ngIf="routerChanged"></div>
And you don't need any more to repeat the same spinner html in all
your pages.
我在整个项目中使用类似于 <app-display-loading>
的东西,我需要做的就是
<app-display-loading *ngIf="isLoading"></app-display-loading>
但是首先你需要在组件所在的模块中添加DisplayLoadingComponent
class这样
exports = [DisplayLoadingComponent]
declarations = [DisplayLoadingComponent]
<ng-container *ngIf="!isLoading">
<form [formGroup]="myForm" novalidate (ngSubmit)="submit()" >
// form content
</form>
</ng-container>
<app-display-loading *ngIf="isLoading"></app-display-loading>
设置正在加载accordingly.and,
在 submit()
中设置防止默认值
您好,您可以使用 HTTP 拦截器在每个请求中显示微调框。
您可以检查this。可能对你有帮助。为了调节微调器,您可以使用公共服务中的变量。
或者您可以在更高级别上使用您的加载组件,通过 CSS 您可以在整个页面上显示加载,因此您不需要其他条件部分。
Angular 结构指令可以帮助我们在 ngIf 指令的 else 部分指向其他组件。
您需要做的就是创建补充内置 ngIf 指令的指令。
最终语法应如下所示:
<div *ngIf="model withLoading">
Model
</div>
这只是糖:
<ng-template [ngIf]="model" [ngIfWithLoading]="null">
<div>
Model
</div>
</ng-template>
这里是指令本身:
@Directive({
selector: '[ngIfWithLoading]',
})
export class LoadingDirective {
@Input() set ngIf(val: any) {
if (!val) {
const factory = this.resolver.resolveComponentFactory(LoadingComponent);
this.vcRef.createComponent(factory)
}
};
constructor(private vcRef: ViewContainerRef, private resolver: ComponentFactoryResolver) { }
}
因此,一旦模型为假,上面的指令就会放置您的 LoadingComponent
而不是模型模板。
不要忘记将 LoadingComponent
包含到 entryComponents
数组中
另见
随着 *ngIf
这是我当前的代码,我在每个页面上使用加载微调器直到 API 响应 returns
<ng-container *ngIf="!isLoading; else spinner">
<form [formGroup]="myForm" novalidate (ngSubmit)="submit()" >
// form content
</form>
</ng-container>
<ng-template #spinner>
<div class="fa-3x tc">
<i class="fas fa-spinner fa-spin"></i>
</div>
</ng-template>
这样我们必须在每个页面上编写相同的 #spinner 组件,所以我创建了一个具有相同内容的组件。
import { Component } from '@angular/core';
@Component({
selector: 'app-display-loading',
styles: [`.load__spinner { color: black; text-align: center; font-size: 30px;}`],
template: `
<ng-template>
<div class="load__spinner"> <i class="fas fa-spinner fa-spin"></i></div>
</ng-template>
`,
preserveWhitespaces: true
})
export class DisplayLoadingComponent {
constructor() {
console.log('display loading called');
}
}
现在我的问题是如何在 *ngIf
中使用这个<app-display-loading>
组件
或者这可能不是正确的方法。请建议如何执行此操作。
您可以使用 ng-template
来做到这一点,例如:
<div *ngIf="test; else otherTest"></div>
<ng-template #otherTest>
<app-display-loading></app-display-loading>
</ng-template>
更新: 如果您正在使用路由,那么这个示例对您很有用:
在您的 AppComponent 中,您可以订阅导航更改
当 NavigationStart
显示您的微调器时,当 NavigationEnd
隐藏微调器时。
AppModule:
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { FormsModule } from '@angular/forms';
import { RouterModule, Routes } from '@angular/router';
import { AppComponent } from './app.component';
import { NavbarComponent } from './navigation/navbar/navbar';
import { HomeComponent } from './views/home/home';
import { CategoriesComponent } from './views/categories/categories';
const routes: Routes = [
{ path: '', redirectTo: '/home', pathMatch: 'full' },
{ path: 'home', component: HomeComponent },
{ path: 'categories', component: CategoriesComponent }
];
@NgModule({
imports: [
BrowserModule,
FormsModule,
RouterModule.forRoot(routes)
],
declarations: [
AppComponent,
NavbarComponent,
HomeComponent,
CategoriesComponent
],
bootstrap: [AppComponent]
})
export class AppModule { }
AppComponent:
import { Component } from '@angular/core';
import { Router, NavigationStart, Event, NavigationEnd } from '@angular/router';
@Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
timeout;
routerChanged = true;
constructor(private router: Router) {
router.events.subscribe((event: Event) => {
if (event instanceof NavigationStart) {
// Show spinner
this.routerChanged = true;
}
if (event instanceof NavigationEnd) {
// Hide spinner
this.timeout = setTimeout(() => {
clearTimeout(this.timeout);
this.routerChanged = false;
}, 1000);
}
});
}
}
应用组件Html:
<app-navbar></app-navbar>
<router-outlet></router-outlet>
<div class="spinner" *ngIf="routerChanged"></div>
And you don't need any more to repeat the same spinner html in all your pages.
我在整个项目中使用类似于 <app-display-loading>
的东西,我需要做的就是
<app-display-loading *ngIf="isLoading"></app-display-loading>
但是首先你需要在组件所在的模块中添加DisplayLoadingComponent
class这样
exports = [DisplayLoadingComponent]
declarations = [DisplayLoadingComponent]
<ng-container *ngIf="!isLoading">
<form [formGroup]="myForm" novalidate (ngSubmit)="submit()" >
// form content
</form>
</ng-container>
<app-display-loading *ngIf="isLoading"></app-display-loading>
设置正在加载accordingly.and, 在 submit()
中设置防止默认值您好,您可以使用 HTTP 拦截器在每个请求中显示微调框。
您可以检查this。可能对你有帮助。为了调节微调器,您可以使用公共服务中的变量。
或者您可以在更高级别上使用您的加载组件,通过 CSS 您可以在整个页面上显示加载,因此您不需要其他条件部分。
Angular 结构指令可以帮助我们在 ngIf 指令的 else 部分指向其他组件。
您需要做的就是创建补充内置 ngIf 指令的指令。
最终语法应如下所示:
<div *ngIf="model withLoading">
Model
</div>
这只是糖:
<ng-template [ngIf]="model" [ngIfWithLoading]="null">
<div>
Model
</div>
</ng-template>
这里是指令本身:
@Directive({
selector: '[ngIfWithLoading]',
})
export class LoadingDirective {
@Input() set ngIf(val: any) {
if (!val) {
const factory = this.resolver.resolveComponentFactory(LoadingComponent);
this.vcRef.createComponent(factory)
}
};
constructor(private vcRef: ViewContainerRef, private resolver: ComponentFactoryResolver) { }
}
因此,一旦模型为假,上面的指令就会放置您的 LoadingComponent
而不是模型模板。
不要忘记将 LoadingComponent
包含到 entryComponents
数组中
另见