【问题标题】:Custom Angular 2+ Stepper module自定义 Angular 2+ 步进模块
【发布时间】:2019-10-24 16:46:31
【问题描述】:

一开始我想说我知道有准备好使用 CDK 或 Materials 的步进器,但我想创建“我自己的”以学习 Angular 8。

说实话,我现在不知道应该在哪里寻求帮助,这就是我决定在这里写的原因。也许有人给我一些建议,我会在最后发表我的作品。

让我们开始吧: 索引 HTML 代码如下所示:

<stepper>
<step>
    <ng-template step-label>First name</ng-template>
    <input placeholder="First name" required>
    <div>
        <button >Next</button>
    </div>
</step>
<step>
    <ng-template step-label>Last name</ng-template>
    <input placeholder="Last name" required>
    <div>
        <button >Next</button>
    </div>
</step>
<step>
    <ng-template step-label>Address name</ng-template>
    <input placeholder="Address" required>
    <div>
        <button >Next</button>
    </div>
</step>
</stepper>

组件+指令

@Directive({selector: '[step-label]'})
export class StepLabel{
    constructor(public template: TemplateRef<any>){};
}

@Component({selector: 'step-header', templateUrl: 'step-header.html'})
export class StepHeader{ 

    @Input() label: TemplateRef<StepLabel>;
}

@Component({
    selector: 'step',
    template: '<ng-template><ng-content></ng-content></ng-template>'
})
export class Step{ 

    @ViewChild(TemplateRef, {static: true}) content: TemplateRef<Step>;
    @ContentChild(StepLabel, {static: true}) label: TemplateRef<StepLabel>;

}

@Component({selector: 'stepper', templateUrl: './stepper.html'})
export class Stepper implements AfterContentInit {
    stepsArray = [];
    @ContentChildren(Step) steps: QueryList<Step>;

    ngAfterContentInit() {
        this.stepsArray = this.steps.toArray();
    }
}

stepper.html

 <div class="header-steps" style="bordeR: 1px solid green; padding: 10px;">
    <ng-container *ngFor="let step of stepsArray; let i = index; let isLast = last">
        <step-header [label]="step.label"></step-header>
    </ng-container>
</div>

<div style="border: 1px solid blue; padding: 5px; margin: 5px;" class="content-steps">      
    <div *ngFor="let step of stepsArray; let i = index">
        <ng-container *ngIf="step" [ngTemplateOutlet]="step.content"></ng-container>
    </div>
</div>

step=header.html

<div class="step-label">
  <ng-container *ngIf="label" [ngTemplateOutlet]="label.template"></ng-container>
</div>

我已经更新了整个“基本”项目。有用。 我有一个问题。为什么在指令 StepLabel 中必须是构造函数。 我试图添加一些这样的想法:

@ViewChild(TemplateRef, {static: true}) template: TemplateRef<StepLabel>;

但它不起作用。

【问题讨论】:

  • 不确定我是否遵循 - 你所说的“为什么在指令 StepLabel 中必须是构造函数”是什么意思。 ?
  • 我想我明白你的意思了 - 为什么 TemplateRef 应该通过构造函数而不是 ViewChild 注入。指令没有模板,因此使用在模板中搜索的 ViewChild 没有任何意义。

标签: angular8 stepper


【解决方案1】:

在您的步骤组件的模板中,将 ng-content 包装在 ng-template 中

template: '<ng-template><ng-content></ng-content></ng-template>'

然后使用ViewChild获取模板

@ViewChild(TemplateRef, { static: true }) content: TemplateRef<any>;

最后你会得到类似的东西:

@Component({
    selector: 'step',
    template: '<ng-template><ng-content></ng-content></ng-template>'
})
export class Step { 
    @ViewChild(TemplateRef, { static: true }) content: TemplateRef<any>;
}

【讨论】:

  • 谢谢。有用。你能解释一下为什么选择器“步骤”的模板必须是这样的吗?
  • ngTemplateOutlet 指令需要 TemplateRef。获得它的一种方法是使用 ng-template。因此,通过将 ng-content 包装到 ng-template 中,您基本上可以将元素的内容放入 TemplateRef。
  • 谢谢。我已经更新了项目,我还有一个问题(关于构造函数)。如果你可以请回答。
猜你喜欢
  • 1970-01-01
  • 2016-12-24
  • 2018-03-09
  • 2017-12-06
  • 2019-05-27
  • 1970-01-01
  • 2017-02-20
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多