【问题标题】:Conditional Rending of a Angular Component [closed]Angular 组件的条件渲染
【发布时间】:2022-01-18 16:04:54
【问题描述】:

我正在使用 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 创建了可重用的组件。谁能帮帮我?

【问题讨论】:

  • 为什么要在ts文件中实现这个?您可以做的是在模板中实现循环,并使用开关可以渲染其中一个组件。

标签: angular typescript ionic-framework


【解决方案1】:

您可以通过使用组件工厂解析器生成组件并将它们附加到某些 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-Docs
  4. Thomas 关于使用 ng-switchcase 的实现的评论也是合法的,而且可能更直接

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2017-12-04
    • 2019-08-07
    • 1970-01-01
    • 2019-06-20
    • 2020-09-19
    • 1970-01-01
    • 1970-01-01
    • 2021-06-07
    相关资源
    最近更新 更多