Angualr cdk 学习之 Stepper

       cdk Stepper 让我们能够更好的处理类似于工作流的情况(任务分为多个步骤,上一步操作完成之后进入下一步的操作,比如咱们休假申请单要经过多个领导的审批的情况)。

       还是和之前cdk 里面其他功能模块一样,要使用Stepper 需provider CdkStepperModule的。

import {CdkStepperModule} from '@angular/cdk/stepper';

       cdk Stepper看起来复杂其实里面的东西不是很多。整个Stepper都是围绕一个组件CdkStep(cdk-step)和6个指令(CdkStepper、CdkStepLabel、CdkStepperNext、CdkStepperPrevious、CdkStepHeader)来展开的。咱们上面不是说了么,cdk Stepper一般用来处理多个步骤任务。这里每个任务的内容用CdkStep组件来表示,所以有多少个步骤就会 有多少个CdkStep组件。CdkStepper指令呢则是用来管理这些组件比如跳到下一步,上一步,完成等等(所以cdk Stepper使用的时候我们需要另外定义一个组件继承自CdkStepper指令,我们可以把他当做是工作流组件)。CdkStepperNext、CdkStepperPrevious两个指令正好对应上一步下一步,一般会添加在button上面包含在CdkStep组件里面,因为每个步骤都可能有上一步,下一步这样的。CdkStepLabel指令则是对每一个步骤的描述你也可以认为是每个步骤的标题。CdkStepHeader指令一般则是用来表示当前进行到哪一步了。一般也是会自定义一个组件继承CdkStepHeader实现。

一 CdkStep

       CdkStep其实是一个组件来着。表示每个步骤的内容。所以任务有多少步就会有多少个CdkStep。比如如下代码有两个步骤所以有两个CdkStep(cdk-step):

<h1>cdk stepper</h1>
<yx-stepper>
    <cdk-step [stepControl]="frmStep1" #step1="cdkStep">
        <ng-template cdkStepLabel>第一步</ng-template>
        <form #frmStep1="ngForm">
            <input type="text" name="a" value="a"/>
        </form>
        <button style="margin: 8px" cdkStepperNext type="button">下一步</button>
    </cdk-step>
    <cdk-step cdkStep #step2="cdkStep">
        <ng-template cdkStepLabel>第二步</ng-template>
        <form #frmStep2="ngForm">
            <input type="text" name="b" value="b"/>
        </form>
        <button cdkStepperPrevious type="button">上一步</button>
        <button style="margin: 8px" cdkStepperNext type="button">完成</button>
    </cdk-step>
</yx-stepper>

       每个CdkStep组件里面的内容对应每个步骤的内容。

       Selector: cdk-step

       Exported as: cdkStep

1.1 CdkStep组件属性

属性 内容 解释
ariaLabel: string @Input('aria-label') 添加aria-label属性
ariaLabelledby: string @Input('aria-labelledby') 添加aria-labelledby属性
completed: boolean @Input() 当前步骤是否标记为完成状态
editable: boolean @Input() 当前步骤标记为完成之后,是否还可以回到该步骤
errorMessage: string @Input() 错误信息
hasError: boolean @Input() 是否有错误
label: string @Input() 当前步骤对应的label,和cdkStepLabel指令的作用是一样的(可以简单的把他认为是步骤的标题)
optional: boolean @Input() 当前步骤是否是可选的
state: StepState @Input() 当前步骤的状态
stepControl: AbstractControl @Input() 用于验证当前步骤的合法性
content: TemplateRef<any> 当前步骤 试图元素内容
interacted: false 用户是否看到当前步骤内容
stepLabel: CdkStepLabel 当前步骤label内容

1.2 CdkStep组件方法

export declare class CdkStep implements OnChanges {
    ...
    /** 选中当前步骤(select哪个步骤则选中那个步骤) */
    select(): void;
    /** 设置当前步骤到无效状态 */
    reset(): void;
    ...
}

CdkStep组件里面大部分的方法都需要配合我们下面要讲的CdkStepper指令来使用

二 CdkStepper

       CdkStepper是一个指令,用来管理所有的步骤,即CdkStepper是用来管理CdkStep组件的。一般的做法是自定义一个组件继承CdkStepper指令。并且CdkStep组件是这个组件的子组件。比如如下的代码我们定义一个StepperComponent组件继承CdkStepper指令:

import {
    AfterContentInit,
    ChangeDetectionStrategy,
    Component,
    ContentChildren,
    EventEmitter,
    Output,
    QueryList,
    ViewEncapsulation
} from '@angular/core';
import {AnimationEvent} from '@angular/animations';
import {CdkStep, CdkStepper, StepContentPositionState} from '@angular/cdk/stepper';
import {Subject} from 'rxjs';
import {distinctUntilChanged, takeUntil} from 'rxjs/operators';
import {yxStepperAnimations} from './stepper-animations';

@Component({
    selector: 'yx-stepper',
    templateUrl: './stepper.component.html',
    styleUrls: ['./stepper.component.less'],
    providers: [{provide: CdkStepper, useExisting: StepperComponent}],
    animations: [yxStepperAnimations.horizontalStepTransition],
    encapsulation: ViewEncapsulation.None,
    changeDetection: ChangeDetectionStrategy.OnPush,
})
export class StepperComponent extends CdkStepper implements AfterContentInit {

    /** Steps that the stepper holds. */
    @ContentChildren(CdkStep) _steps: QueryList<CdkStep>;

    /** Event emitted when the current step is done transitioning in. */
    @Output() readonly animationDone: EventEmitter<void> = new EventEmitter<void>();

    _animationDone = new Subject<AnimationEvent>();

    ngAfterContentInit() {

        // Mark the component for change detection whenever the content children query changes
        this._steps.changes.pipe(takeUntil(this._destroyed)).subscribe(() => this._stateChanged());

        this._animationDone.pipe(
            // This needs a `distinctUntilChanged` in order to avoid emitting the same event twice due
            // to a bug in animations where the `.done` callback gets invoked twice on some browsers.
            // See https://github.com/angular/angular/issues/24084
            distinctUntilChanged((x, y) => x.fromState === y.fromState && x.toState === y.toState),
            takeUntil(this._destroyed)
        ).subscribe(event => {
            if ((event.toState as StepContentPositionState) === 'current') {
                this.animationDone.emit();
            }
        });
    }
}

       Selector: [cdkStepper]

       Exported as: cdkStepper

2.1 CdkStepper属性

属性 类型 解释
linear: boolean @Input() 任务流是否是线性的,前一个任务完成才能进行下一个任务
selected: CdkStep @Input() 当前选中的任务
selectedIndex: number @Input() 当前选中任务的index
selectionChange: EventEmitter<StepperSelectionEvent> @Output() 选中任务改变时候的回调函数

2.2 CdkStepper方法

export declare class CdkStepper implements AfterViewInit, OnDestroy {
    ...
    /** 切换到下一个任务 */
    next(): void;
    /** 切换到上一个任务 */
    previous(): void;
    /** 重置所有的任务 */
    reset(): void;
    ...
}

关于CdkStepper的使用更加详细的任务可以参考下下文中代码链接。

三 CdkStepLabel

       指令,每个步骤需要显示的label内容,比如如下代码<ng-template cdkStepLabel>第一步</ng-template>部分就是某个任务的label。

    <cdk-step [stepControl]="frmStep1" #step1="cdkStep">
        <ng-template cdkStepLabel>第一步</ng-template>
        <form #frmStep1="ngForm">
            <input type="text" name="a" value="a"/>
        </form>
        <button style="margin: 8px" cdkStepperNext type="button">下一步</button>
    </cdk-step>

       Selector: [cdkStepLabel]

四 CdkStepperNext

       添加在button上的指令,跳到下一个任务。

       Selector: button[cdkStepperNext]

五 CdkStepperPrevious

       添加在button上的指令,跳到上一个任务。

       Selector: button[cdkStepperPrevious]

六 CdkStepHeader

       指令,每个任务的头部信息,任务指示器。


       关于cdk Stepper部分的内容好像也没啥讲的,关键点就在咱们继承CdkStepper的组件怎么来写了,怎么来管理这些workflow里面的任务。所以最最重要的在代码实现部分。为了能让大家更加直观的知道cdk Stepper怎么使用,这里我就直接写了一个非常简单的例子。有兴趣的大家可以看看例子里面是怎么做到的 https://github.com/tuacy/angular-cdk-study cdk stepper部分内容在workflow-stepper文件下面。实现效果图如下:

stepper.gif
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 198,932评论 5 466
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 83,554评论 2 375
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 145,894评论 0 328
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 53,442评论 1 268
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 62,347评论 5 359
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 47,899评论 1 275
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,325评论 3 390
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 35,980评论 0 254
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,196评论 1 294
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,163评论 2 317
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,085评论 1 328
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 32,826评论 3 316
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,389评论 3 302
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,501评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 30,753评论 1 255
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 42,171评论 2 344
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 41,616评论 2 339

推荐阅读更多精彩内容

  • Swift1> Swift和OC的区别1.1> Swift没有地址/指针的概念1.2> 泛型1.3> 类型严谨 对...
    cosWriter阅读 11,074评论 1 32
  • cdk ally里面提供的功能运用场景是 select, menu 这种有 list options 的组件...
    tuacy阅读 1,153评论 0 1
  • 一、首先我先把集成过程说一下。小编想说的话:支付宝是我做支付中觉得坑最多的一个,各种编译不过,各种出问题。 废话不...
    左先生丶丶阅读 10,474评论 5 11
  • 春天来了。3月11-12日,携同学10多人去距离重庆320公里的开州十里竹溪春游。 11日早,我开车并搭上太太及三...
    樊荣强阅读 367评论 6 6
  • 欢乐颂里面的安迪,简直就是女人的榜样。想到安迪就觉得女人就该努力,让别人不敢随便欺负你! 安迪的皮肤好,打扮也时尚...
    sarol阅读 167评论 0 0