Ash*_*jar 19 angular-material2
如何在角度分量与相同的步进步骤之间切换mat-vertical-stepper和mat-horizontal-stepper?
从 Angular 12 开始(特别是这些 PR: https: //github.com/angular/components/pull/21940和https://github.com/angular/components/pull/22139),您现在可以使用MatStepper(请注意MatHorizontalStepper,MatVerticalStepper在这些 PR 中已弃用)并根据需要设置方向输入:
<mat-stepper [orientation]="orientation">
<mat-step>Step 1</mat-step>
<mat-step>Step 2</mat-step>
</mat-stepper>
Run Code Online (Sandbox Code Playgroud)
为了避免重写相同的html内容,请执行以下操作。创建模板,并使用提供参考#hashtag。然后您可以使用来插入它们ng-container *ngTemplateOutlet="hashtag"></ng-container>。
这是制作有角度的阶梯式反应性阶梯的示例。
<ng-template #stepOne>
<div>step one</div>
</ng-template>
<ng-template #stepTwo>
<div>step two</div>
</ng-template>
<ng-template #stepThree>
<div>step three</div>
</ng-template>
<ng-template #stepFour>
<div>step four</div>
</ng-template>
<ng-template [ngIf]="smallScreen" [ngIfElse]="bigScreen">
<mat-vertical-stepper linear #stepper >
<mat-step>
<ng-container *ngTemplateOutlet="stepOne"></ng-container>
</mat-step>
<mat-step>
<ng-container *ngTemplateOutlet="stepTwo"></ng-container>
</mat-step>
<mat-step>
<ng-container *ngTemplateOutlet="stepThree"></ng-container>
</mat-step>
<mat-step>
<ng-container *ngTemplateOutlet="stepFour"></ng-container>
</mat-step>
</mat-vertical-stepper>
</ng-template>
<ng-template #bigScreen>
<mat-horizontal-stepper linear #stepper >
<mat-step>
<ng-container *ngTemplateOutlet="stepOne"></ng-container>
</mat-step>
<mat-step >
<ng-container *ngTemplateOutlet="stepTwo"></ng-container>
</mat-step>
<mat-step>
<ng-container *ngTemplateOutlet="stepThree"></ng-container>
</mat-step>
<mat-step>
<ng-container *ngTemplateOutlet="stepFour"></ng-container>
</mat-step>
</mat-horizontal-stepper>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
您可以使用角度cdk布局来跟踪屏幕尺寸,如下所示。
import { Component } from '@angular/core';
import {BreakpointObserver, Breakpoints} from '@angular/cdk/layout';
@Component({
selector: 'app-responsive-stepper',
templateUrl: './responsive-stepper.component.html',
styleUrls: ['./responsive-stepper.component.scss']
})
export class ResponsiveStepperComponent implements OnInit {
smallScreen: boolean;
constructor(
private breakpointObserver: BreakpointObserver
) {
breakpointObserver.observe([
Breakpoints.XSmall,
Breakpoints.Small
]).subscribe(result => {
this.smallScreen = result.matches;
});
}
}
Run Code Online (Sandbox Code Playgroud)
我将Teradata的Covalent组件与Google的Material组件一起使用。他们使用物料设计,甚至以与Google物料模块相同的方式导入模块。
Covalent的步进器在设置时会考虑模式输入,因此您可以像这样实现HTML模板:
<td-steps [mode]="stepperMode">
<td-step>
...
</td-step>
...
</td-steps>
Run Code Online (Sandbox Code Playgroud)
然后,在组件的打字稿文件中,可以根据需要将变量设置为水平或垂直变量:
if (condition) {
stepperMode = 'horizontal';
} else {
stepperMode = 'vertical';
}
Run Code Online (Sandbox Code Playgroud)
我想做同样的事情,并最终弄清楚了如何使它工作,并完整地包含了步骤等内容,此外,您还可以在水平和垂直之间同步当前选择的索引,这样就不会改变页面大小将人员重置为步骤1。
这是一个完整的例子。
包装器组件HTML:
<ng-template #horizontal>
<mat-horizontal-stepper #stepper
[linear]="isLinear"
(selectionChange)="selectionChanged($event)">
<mat-step *ngFor="let step of steps; let i = index"
[stepControl]="step.form"
[label]="step.label"
[optional]="step.isOptional">
<ng-container *ngTemplateOutlet="step.template"></ng-container>
<div class="actions">
<div class="previous">
<button *ngIf="i > 0"
type="button" mat-button
color="accent"
(click)="reset()"
matTooltip="All entries will be cleared">Start Over</button>
<button *ngIf="i > 0"
type="button" mat-button
matStepperPrevious>Previous</button>
</div>
<div class="next">
<button type="button" mat-button
color="primary"
matStepperNext
(click)="step.submit()">{{i === steps.length - 1 ? 'Finish' : 'Next'}}</button>
</div>
</div>
</mat-step>
</mat-horizontal-stepper>
</ng-template>
<ng-template #vertical>
<mat-vertical-stepper #stepper
[linear]="isLinear"
(selectionChange)="selectionChanged($event)">
<mat-step *ngFor="let step of steps; let i = index"
[stepControl]="step.form"
[label]="step.label"
[optional]="step.isOptional">
<ng-container *ngTemplateOutlet="step.template"></ng-container>
<div class="actions">
<div class="previous">
<button *ngIf="i > 0"
type="button" mat-button
color="accent"
(click)="reset()"
matTooltip="All entries will be cleared">Start Over</button>
<button *ngIf="i > 0"
type="button" mat-button
matStepperPrevious>Previous</button>
</div>
<div class="next">
<button type="button" mat-button
color="primary"
matStepperNext
(click)="step.submit()">{{i === steps.length - 1 ? 'Finish' : 'Next'}}</button>
</div>
</div>
</mat-step>
</mat-vertical-stepper>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
包装器组件ts:
import { Component, OnInit, OnDestroy, Input, ContentChildren, QueryList, ViewChild, TemplateRef } from '@angular/core';
import { BreakpointObserver, BreakpointState } from '@angular/cdk/layout';
import { StepComponent } from './step/step.component';
import { Subscription } from 'rxjs';
import { MatStepper } from '@angular/material';
@Component({
selector: 'stepper',
templateUrl: './stepper.component.html',
styleUrls: ['./stepper.component.scss']
})
export class StepperComponent implements OnInit, OnDestroy {
public selectedIndex: number = 0;
public isMobile: boolean;
public template: TemplateRef<any>;
@Input() isLinear: boolean = true;
@Input() startAtIndex: number;
@ContentChildren(StepComponent) private steps: QueryList<StepComponent>;
@ViewChild('horizontal') templHorizontal: TemplateRef<any>;
@ViewChild('vertical') templVertical: TemplateRef<any>;
@ViewChild('stepper') stepper: MatStepper;
private _bpSub: Subscription;
constructor(private bpObserver: BreakpointObserver) { }
ngOnInit() {
this._bpSub = this.bpObserver
.observe(['(max-width: 599px)'])
.subscribe((state: BreakpointState) => {
this.setMobileStepper(state.matches);
});
if (this.startAtIndex) {
this.selectedIndex = this.startAtIndex;
}
}
selectionChanged(event: any): void {
this.selectedIndex = event.selectedIndex;
}
setMobileStepper(isMobile: boolean): void {
this.isMobile = isMobile;
if (isMobile) {
this.template = this.templVertical;
}
else {
this.template = this.templHorizontal;
}
setTimeout(() => {
// need async call since the ViewChild isn't ready
// until after this function runs, thus the setTimeout hack
this.stepper.selectedIndex = this.selectedIndex;
});
}
reset(): void {
this.stepper.reset();
}
ngOnDestroy(): void {
this._bpSub.unsubscribe();
}
}
Run Code Online (Sandbox Code Playgroud)
步骤组件HTML:
<ng-template #template>
<ng-content></ng-content>
</ng-template>
Run Code Online (Sandbox Code Playgroud)
步骤组件ts:
import { Component, Input, Output, TemplateRef, ViewChild, EventEmitter } from '@angular/core';
import { FormGroup } from '@angular/forms';
@Component({
selector: 'stepper-step',
templateUrl: './step.component.html',
styleUrls: ['./step.component.scss']
})
export class StepComponent {
@Input() isOptional: boolean = false;
@Input() label: string;
@Input() form: FormGroup;
@ViewChild('template') template: TemplateRef<any>;
@Output() formSubmitted: EventEmitter<any> = new EventEmitter();
constructor() { }
submit(): void {
this.formSubmitted.emit(this.form.value);
}
}
Run Code Online (Sandbox Code Playgroud)
在组件HTML中使用响应式Angular Material Stepper:
<stepper>
<stepper-step
label="Step 1 label"
[form]="step1form"
(formSubmitted)="form1Submit($event)">
content
<form [formGroup]="frmStep1">
<mat-form-field>
<input matInput name="firstname" formControlName="firstname" placeholder="First Name" />
</mat-form-field>
content
</form>
</stepper-step>
<stepper-step
label="Step 2 label"
[form]="step2form">
step 2 content
</stepper-step>
</stepper>
Run Code Online (Sandbox Code Playgroud)
以及表单所需的组件功能:
form1Submit(formValues: any): void {
console.log(formValues);
}
Run Code Online (Sandbox Code Playgroud)
您可能想要创建两个单独的步进器并使用 *ngIf 在它们之间切换
<mat-vertical-stepper *ngIf="verticalFlag">
<mat-step>
</mat-step>
</mat-vertical-stepper>
<mat-horizontal-stepper *ngIf="!verticalFlag">
<mat-step>
</mat-step>
</mat-horizontal-stepper>
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
6230 次 |
| 最近记录: |