我在Angular中遇到以下问题,我无法摆脱困境。
让我们假设有一个Angular Wizard
组件。该向导组件具有约10个输入/输出参数,如initialStep
,onSubmit
,onStepChange
,currentStep
,isLoading
等。
现在,我需要使用向导创建3个页面。第1页有步骤1,第2页有步骤2,第3页有步骤1& 2& 3.它在标记中的样子:
Wizard1:
<wizard *ngIf="process" initialStep="0" (onSubmit)="onSubmit()" (onStepChange)="onStepChange($event)" [loading]="loading" infoPaletteText="You cannot submit" title="title1">
<wizard-step caption="steptitle1">
<step1-content></step1-content>
</wizard-step>
</wizard>
向导2:
<wizard *ngIf="process" initialStep="0" (onSubmit)="onSubmit()" (onStepChange)="onStepChange($event)" [loading]="loading" infoPaletteText="You cannot submit" title="title2">
<wizard-step caption="steptitle2">
<step2-content></step2-content>
</wizard-step>
</wizard>
Wizard3:
<wizard *ngIf="process" initialStep="0" (onSubmit)="onSubmit()" (onStepChange)="onStepChange($event)" [loading]="loading" infoPaletteText="You cannot submit" title="title3">
<wizard-step caption="steptitle1">
<step1-content></step1-content>
</wizard-step>
<wizard-step caption="steptitle2">
<step2-content></step2-content>
</wizard-step>
<wizard-step caption="steptitle3">
<summary></summary>
</wizard-step>
</wizard>
如您所见,向导组件定义对于所有组件绝对相同。标题是唯一的易变参数。我需要某种currying或组合,我得到带有1个参数的新向导组件,其余的都是固定的。
Angular不鼓励继承组件,也不继承模板。因此,无论组件是什么,我都希望将向导的onSubmit
方法绑定到onSubmit
方法,loading
绑定到loading
变量等。
如何以正确和聪明的方式解决这个问题?
修改
受到this article的启发,我决定尝试这种疯狂的方式:
为静态类型检查创建界面:
export interface ISurveyAttachable {
onSubmit(): void;
onStepChange(event): void;
loading: boolean;
}
创建指令,该指令只能附加到向导组件
@Directive({
selector: 'wizard[survey]'
})
export class SurveyWizardDirective implements DoCheck, OnDestroy {
private subs = [];
@Input('survey')
set param(value: ISurveyAttachable) {
this.attachableComponent = value;
this.unsibscribe();
if (!value) return;
this.subs.push(this.wizardForm.onStepChange.subscribe(value.onStepChange.bind(value)));
this.subs.push(this.wizardForm.onSubmit.subscribe(value.onSubmit.bind(value)));
}
get param() : ISurveyAttachable{
return this.attachableComponent;
}
private attachableComponent: ISurveyAttachable;
constructor(private wizardForm: WizardComponent) { }
ngDoCheck(): void {
if (!this.attachableComponent) {
return;
}
this.wizardForm.loading = this.attachableComponent.loading;
}
private unsibscribe() {
this.subs.forEach((sub) => sub.unsubscribe());
this.subs = [];
}
ngOnDestroy(): void {
this.unsibscribe();
}
}
然后,我可以在目标组件中以这种方式使用指令:
<wizard *ngIf="process" [survey]="this">
<!--steps here-->
</wizard>
因此,它表明我的想法是可行的,但它有许多缺点:
this
变量看起来很难看。可以在@Component声明中附加指令。但在这种情况下,我忽略了WizardComponent
。我认为上面的解决方案更像是Angular高级主题中的练习而不是生产就绪代码。然而,这个需要在3个地方更新相同代码的地方过去已经造成了一些错误。
感谢任何新想法。
答案 0 :(得分:-1)
您被迫将事件发射器绑定到父级。
否则,您必须使用服务。我们假设它被称为WizardService
。
然后在你的代码中,而不是写
this.onSubmit.emit(value);
你会写
this.service.submit(value);
你的HTML代码会减少。如果只有标题发生变化,那么你只有这个
<wizard title="title1">
<!-- your content -->
</wizard>