Angular 组件的条件渲染

Posted

技术标签:

【中文标题】Angular 组件的条件渲染【英文标题】:Conditional Rending of a Angular Component [closed] 【发布时间】: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文件中实现这个?您可以做的是在模板中实现循环,并使用开关可以渲染其中一个组件。 【参考方案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

旁注:

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

【讨论】:

以上是关于Angular 组件的条件渲染的主要内容,如果未能解决你的问题,请参考以下文章

Angular2:如何在渲染组件之前加载数据?

Angular2:如何在渲染组件之前加载数据?

Angular - 动态组件渲染错误数据

Angular 9 - 渲染有限数量的组件的孩子

Angular 6 - 将子组件渲染为父组件中的内容

如何在 Angular 2 中强制组件重新渲染?