Loc*_*cke 5 angular-material angular-material2 angular angular-material-stepper
在 Angular 中,是否可以有一个线性步进器,其中各个步骤是单独的组件?例如:
<mat-horizontal-stepper [linear]="isLinear">
<mat-step [stepControl]="firstFormGroup" label="Some Form">
<first-component></first-component>
</mat-step>
<mat-step [stepControl]="secondFormGroup" label="Another Form">
<second-component></second-component>
</mat-step>
<mat-step [stepControl]="thirdFormGroup" label="Review">
<third-component></third-component>
</mat-step>
</mat-horizontal-stepper>
Run Code Online (Sandbox Code Playgroud)
当我尝试这个时,我在点击matStepperNext按钮时收到以下错误:
TypeError: Cannot read property 'invalid' of undefined.
这是对我有用的解决方案。
<mat-horizontal-stepper [linear]="true" #stepper>
<mat-step [stepControl]="selectAdvType">
<ng-template matStepLabel>
<div class="text-center">
<mat-icon>queue_play_next</mat-icon><br /><span>Select Adv Type</span>
</div>
</ng-template>
<app-advertisement-type></app-advertisement-type>
</mat-step>
<mat-step [stepControl]="selectAdvType">
<ng-template matStepLabel>
<div class="text-center">
<mat-icon>directions_car</mat-icon><br /><span>Select Car</span>
</div>
</ng-template>
<app-select-car-adv></app-select-car-adv>
</mat-step>
<mat-step>
<ng-template matStepLabel>
<div class="text-center">
<mat-icon>description</mat-icon><br /><span>Select Features</span>
</div>
</ng-template>
<div>
<button mat-button matStepperPrevious>Back</button>
<button mat-button (click)="stepper.reset()">Reset</button>
</div>
</mat-step>
</mat-horizontal-stepper>
Run Code Online (Sandbox Code Playgroud)
父 Ts 文件
@Component({
selector: 'app-customer.create.advertisement',
templateUrl: './customer.create.advertisement.component.html',
styleUrls: ['./customer.create.advertisement.component.scss']
})
export class CustomerCreateAdvertisementComponent implements OnInit {
isLinear = false;
selectAdvType: FormGroup;
constructor(private _formBuilder: FormBuilder) { }
ngOnInit() {
this.selectAdvType = this._formBuilder.group({
firstCtrl: ['', Validators.required]
});
}
}
Run Code Online (Sandbox Code Playgroud)
子组件
<form [formGroup]="firstFormGroup">
<ng-template matStepLabel>Fill out your name</ng-template>
<mat-form-field>
<input matInput placeholder="Last name, First name" formControlName="firstCtrl" required>
</mat-form-field>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</form>
@Component({
selector: 'app-advertisement-type',
templateUrl: './advertisement-type.component.html',
styleUrls: ['./advertisement-type.component.scss']
})
export class AdvertisementTypeComponent implements OnInit {
firstFormGroup: FormGroup;
constructor(private _formBuilder: FormBuilder) { }
ngOnInit() {
this.firstFormGroup = this._formBuilder.group({
firstCtrl: ['', Validators.required]
});
}
}
Run Code Online (Sandbox Code Playgroud)
您可以使用子表单来解决它。几个月前,我实际上在 Angular-UP 会议上发表了关于它的演讲:https : //www.youtube.com/watch?v=sb7tgsNF2Jk
思路,一般来说,就是在子组件中创建表单,使用DI注入controlContainer,并将本地表单设置为controlContainer表单。
子组件:
@Component({
selector: 'app-company-info',
templateUrl: './company-info.component.html',
styleUrls: ['./company-info.component.scss'],
viewProviders: [{ provide: ControlContainer, useExisting: FormGroupDirective }]
})
export class CompanyInfoComponent implements OnInit {
form: FormGroup;
constructor(
private ctrlContainer: FormGroupDirective,
private fb: FormBuilder) { }
ngOnInit() {
this.form = this.ctrlContainer.form;
this.form.addControl('company',
this.fb.group({
'companyName': this.fb.control(null, [Validators.required]),
'numOfEmployees': this.fb.control(null, [Validators.required])});
}
}
Run Code Online (Sandbox Code Playgroud)
父组件(html):
<mat-horizontal-stepper [linear]="isLinear" #stepper>
<mat-step [stepControl]="companyInfo">
<ng-template matStepLabel>Fill out your name</ng-template>
<form [formGroup]="companyInfo">
<app-company-info></app-company-info>
</form>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
</mat-horizontal-stepper>
Run Code Online (Sandbox Code Playgroud)
父组件(ts):
export class WizardComponent implements OnInit {
isLinear = true;
companyInfo: FormGroup;
constructor(private _formBuilder: FormBuilder) {
}
ngOnInit() {
this.companyInfo = this._formBuilder.group({
});
}
}
Run Code Online (Sandbox Code Playgroud)
改进@eliran-eliassy 答案和@christian-steinmeyer 问题。
父组件.ts
export class ParentComponent implements OnInit {
isLinear = true;
companyInfo: FormGroup;
constructor(private _formBuilder: FormBuilder) {
}
ngOnInit() {
this.companyInfo = this._formBuilder.group({
});
}
}
Run Code Online (Sandbox Code Playgroud)
父组件.html
<mat-horizontal-stepper [linear]="isLinear" #stepper>
<mat-step [stepControl]="companyInfo">
<form [formGroup]="companyInfo">
<ng-template matStepLabel>Fill out your name</ng-template>
<app-company-info></app-company-info>
</form>
<div>
<button mat-button matStepperNext>Next</button>
</div>
</mat-step>
</mat-horizontal-stepper>
Run Code Online (Sandbox Code Playgroud)
Child.Component.ts -> 这是子表单
export class ChildComponent implements OnInit {
form: FormGroup;
subForm: FormGroup;
constructor(
private ctrlContainer: FormGroupDirective,
private fb: FormBuilder
) {}
ngOnInit() {
this.subForm = this.fb.group({
companyName: [null, [Validators.required]],
numOfEmployees: [null, [Validators.required]]
});
this.form = this.ctrlContainer.form;
this.form.addControl("company", this.subForm);
}
}
Run Code Online (Sandbox Code Playgroud)
Child.Component.html
<div [formGroup]="subForm">
<mat-form-field appearance="outline">
<input matInput placeholder="Your Company Name" formControlName="companyName">
</mat-form-field>
</div>
Run Code Online (Sandbox Code Playgroud)
在stackblitz上查看此解决方案
| 归档时间: |
|
| 查看次数: |
12395 次 |
| 最近记录: |