角度组件的条件重新编码



我正在使用Ionic和Angular创建一篇简单的MCQ论文。我正在尝试根据JSON数据文件来呈现角度可重用组件。在我的JSON数据数组中,有三种类型的mcq问题。此外,我有三个可重用的组件,我需要根据mcq的类型来渲染它们。我已经使用for循环检查了MCQ的类型,但我不知道如何从ts文件调用组件。

这是我的JSON数据文件

"questions": [
[
{
"index": 1,
"type": "single-select",
"text": "If 5x plus 32 equals 4 minus 2x what is the value of x ?",
"answers": [
{
"index": "A",
"value": "-4"
},
{
"index": "B",
"value": "-3"
},
{
"index": "C",
"value": "4"
},
{
"index": "D",
"value": "7"
},
{
"index": "E",
"value": "12"
}
],
"correctAnswers": {
"indexes": [
"A"
]
},
"points": "10",
"time": "30"
}
],
[
{
"index": 2,
"type": "multi-select",
"text": "let X * Y = 12. What are the possible values for X and Y ?",
"answers": [
{
"index": 1,
"value": "X=4 and Y=3",
"isChecked": false
},
{
"index": 2,
"value": "X=8 and Y=2",
"isChecked": false
},
{
"index": 3,
"value": "X=6 and Y=2",
"isChecked": false
},
{
"index": 4,
"value": "X=3 and Y=5",
"isChecked": false
},
{
"index": 5,
"value": "X=1 and Y=1",
" isChecked": false
}
],
"correctAnswers": {
"indexes": [
1,
3,
5
]
},
"points": "10",
"time": "30"
}
],
[
{
"index": 3,
"type": "dropdown-select",
"text": "What is the 3rd color of the rainbow ?",
"answers": [
{
"index": 1,
"value": "Green"
},
{
"index": 2,
"value": "Red"
},
{
"index": 3,
"value": "Yellow"
},
{
"index": 4,
"value": "Pink"
},
{
"index": 5,
"value": "Blue"
}
],
"correctAnswers": {
"indexes": [
3
]
},
"points": "10",
"time": "30"
}
],
]

我已经使用@Input和@Output创建了可重复使用的组件。有人能帮我吗?

您可以通过使用组件工厂解析器生成组件并将它们附加到某个HTML元素来实现此功能。

首先,您需要一个指令,该指令将用于连接组件

import { Directive, ViewContainerRef } from '@angular/core';
@Directive({
selector: '[appRef]',
})
export class RefDirective {
constructor(public viewContainerRef: ViewContainerRef) {}
}

在你想连接其余组件的组件内部,你将使用类似的指令

<ng-template appRef></ng-template>

你的组件打字脚本看起来像

export class AppComponent {
@ViewChild(RefDirective, { static: true }) ref: RefDirective;
config = [
{
type: 'single',
},
{
type: 'multy',
},
{
type: 'single',
},
{
type: 'dropdown',
},
];
cmpMap = {
single: SingleComponent,
multy: MultyComponent,
dropdown: DropdownComponent,
};
constructor(private componentFactoryResolver: ComponentFactoryResolver) {}
ngOnInit() {
let directiveContainerRef = this.ref.viewContainerRef;
this.config.forEach((x) => {
let cmp = this.componentFactoryResolver.resolveComponentFactory(
this.cmpMap[x.type]
);
directiveContainerRef.createComponent(cmp);
});
}
}

因此,我们正在做的事情是创建一个指令,它的构造函数中有viewContainerRef,我们将把这个指令附加到我们想要插入动态组件的地方。

之后,对于我们想要动态插入模板中的每个组件,我们使用componetFactoryResolver,以便首先创建它,然后,我们通过RefDirective附加它。仅此而已,如果需要,还可以通过viewRef.create返回的引用将数据传递给新创建的组件。

下面是一个实际例子:StackBlitz

旁注:

  1. 您可以创建一个专用组件而不是指令,并将组件附加到组件本身
  2. 如果您使用的是Angular 13,则不需要组件工厂解析器
  3. 这里有一个链接,链接到NG文档的官方示例
  4. Thomas关于使用ng switchcase的实现的评论也是合法的,而且可能更直接

最新更新