如何在 Angular 8 中有条件地加载两个子组件
Posted
技术标签:
【中文标题】如何在 Angular 8 中有条件地加载两个子组件【英文标题】:How can i load two childs components conditionally on Angular 8 【发布时间】:2021-12-11 16:29:16 【问题描述】:考虑以下层次结构:
<app-component>
<university-component></university-component>
<highSchool-component></highSchool-component>
</app-component>
在打开的应用程序组件中显示的对话框组件(dialog-component)包含 2 个选项(大学和高中:
<form nz-form [nzLayout]="'inline'" [formGroup]="validateForm" (ngSubmit)="submitForm()">
<h3> Please select your academic level </h3>
<nz-form-control [nzErrorTip]="getErrorTip('studentLevel')">
<nz-radio-group [(ngModel)]="radioValue" formControlName="studentLevel" nzButtonStyle="solid" nzSize="small">
<input type="radio" name="radio3" id="university" (change)="setRouter(2)">
<label class="universite-label four col" nzValue="universite" for="universite">University</label>
<input type="radio" name="radio3" id="highSchool" (change)="setRouter(1)">
<label class="lycee-label four col" nzValue="lycee" for="lycee" >High School</label>
</nz-radio-group>
</nz-form-control>
<div>
<label nzType="flex" nzJustify="center" nzAlign="middle" nz-radio-button (click)="changeRoute()" mat-dialog-close >GO</label>
</div>
</form>
如果我选择大学,应用程序组件加载大学组件,如果我选择高中,应用程序组件加载 highSchool 组件,我该怎么做
【问题讨论】:
...不确定问题是否正确...您的组件中绑定了radioValue
prop (ngModel-) => 所以<app-componnet> <university-component *ngIf="radioValue === 'someValOfNzRadioGroupValue'></university-component> <highSchool-component *ngIf="radioValue === 'someOhterValOfNzRadioGroupValue'></highSchool-component>
...
如果它可以正常工作的魔法(使用带有 formControlName 的 mgModel)
@Vovan_Super 我尝试了这个解决方案,但没有奏效!因为包含 radiValue 的对话框是一个单独的组件
@НикитаСереда 是的,工作正常...ibb.co/XJWbbD5
【参考方案1】:
我认为您已经将radioValue
绑定到ngModel
,因此您可以执行以下操作,假设AppComponent
可以访问radioValue
<app-component>
<university-component *ngIf="radioValue === 'universityComponentVal'"> </university-compnent>
<high-school-component *ngIf="radioValue === 'highSchoolVal'"></high-school-component>
</app-component>
如果条件渲染组件的数量增加,您可能需要使用ngSwitch
和ngSwtichCase
https://angular.io/api/common/NgSwitchCase
【讨论】:
包含radioValue的对话框是一个单独的组件,我怎么称呼它? 如果是 AppComponent 的子组件,您可以将其作为输入传递,但如果我们需要更新父组件,我们可以通过事件发射器传递它【参考方案2】:我相信ngIf
是最简单的方法,我建议使用路由,除非父组件有共享变量。这也将允许将来进行深度链接,这样您的用户就可以避免每次都需要选择一个值。
export const appRoutes: Routes = [
... Any other routes you have
path: 'university',
component: UniversityComponent,
,
path: 'highSchool',
component: HighSchoolComponent
;
@NgModule(
imports: [
...
RouterModule.forRoot(appRoutes)
]
)
export class AppModule
您可以使用 Angular 中的 routerLink
指令从 html 转到该路由,也可以从表单上调用的当前函数转到该路由。
@Component(
...
)
export class AppComponent
radioValue: 'university' | 'highSchool';
constructor(private router: Router)
changeRoute()
this.router.navigate([this.radioValue]);
您似乎也在将formControlName
与ngModel
联合起来,这可能会导致错误。上述方法是使用ngModel
值,您可以通过访问您的表单值来使用表单值。
【讨论】:
【参考方案3】:谢谢大家的回答,
我找到了解决方案。 我创建了一个服务“level.service.ts”:
import Injectable from '@angular/core';
import Observable, Subject from 'rxjs';
@Injectable(
providedIn: 'root'
)
export class LevelService
isUniversity: boolean = true;
constructor()
highScool()
this.isUniversity = false;
universite()
this.isUniversity = true;
在应用组件中:
<app-component>
<university-component *ngIf="levelService.isUniversity"></university-component>
<highSchool-component *ngIf="!levelService.isUniversity"></highSchool-component>
</app-component>
我在 dialog.component.html 中添加了两个(点击):
<form nz-form [nzLayout]="'inline'" [formGroup]="validateForm" (ngSubmit)="submitForm()">
<h3> Please select your academic level </h3>
<nz-form-control [nzErrorTip]="getErrorTip('studentLevel')">
<nz-radio-group [(ngModel)]="radioValue" formControlName="studentLevel" nzButtonStyle="solid" nzSize="small">
<input type="radio" name="radio3" id="university" (change)="setRouter(2)">
<label class="universite-label four col" nzValue="universite" for="universite" (click)="university()">University</label>
<input type="radio" name="radio3" id="highSchool" (change)="setRouter(1)">
<label class="lycee-label four col" nzValue="lycee" for="lycee" (click)="highSchool()">High School</label>
</nz-radio-group>
</nz-form-control>
<div>
<label nzType="flex" nzJustify="center" nzAlign="middle" nz-radio-button (click)="changeRoute()" mat-dialog-close >GO</label>
</div>
</form>
在 dialog.component.ts 中:
import Component from '@angular/core';
import UniversityService from 'src/app/services/university.service';
// others import
@Component(
selector: 'app-dialog-video',
templateUrl: './dialog-video.component.html',
styleUrls: ['./dialog-video.component.css']
)
export class DialogVideoComponent implements OnInit
@Input() radioValue = 'college'
isUniversity: string = 'universite';
// constructor()
// other logics
ngOnInit()
// this.universityService.isUniversity = this.radioValue;
this.universityService.collegeLycee(),
this.universityService.universite()
highSchool()
this.universityService.collegeLycee();
university()
this.universityService.universite();
【讨论】:
以上是关于如何在 Angular 8 中有条件地加载两个子组件的主要内容,如果未能解决你的问题,请参考以下文章