标签: angular-dynamic-components

使用带有 resolveComponentFactory 的通用组件会导致 Component<{}> 而不是 <T>

我已经构建了一个对话框服务,它动态地创建了一个带有子组件的 DialogComponent。

我希望我的 DialogComponent 是一个泛型类,<T>因为我希望为我正在使用的任何组件子项输入。我目前正在使用这些行创建我的 DialogComponent ->

const componentFactory = this.componentFactoryResolver.resolveComponentFactory(DialogComponent);
const componentRef = componentFactory.create(new DialogInjector(this.injector, map));
Run Code Online (Sandbox Code Playgroud)

问题是 resolveComponentFactory 实际上返回的是一个DialogComponent<{}>而不是T。我确实尝试过投射,但似乎我不能,因为缺少某些方法。

我想知道我怎么能做到这一点!

谢谢。

编辑

this.componentFactoryResolver.resolveComponentFactory<DialogComponent<T>> 做的伎俩..

angular-components angular angular-dynamic-components

5
推荐指数
1
解决办法
1112
查看次数

动态组件上未调用 ngOnInit

我在一个项目中使用 Angular 8,并且在启动动态组件时遇到问题,因为 ngOnInit 没有被调用。我构建了一个名为 PlaceholderDirective 的指令,如下所示:

@Directive({
  selector: '[appPlaceholder]'
})
export class PlaceholderDirective {
  constructor(public viewContainerRef: ViewContainerRef) {}
}
Run Code Online (Sandbox Code Playgroud)

并在 ng-template 上使用该指令:

<ng-template appPlaceholder></ng-template>
Run Code Online (Sandbox Code Playgroud)

保存 ng-template 所在 HTML 的组件启动动态组件,如下所示:

@ViewChild(PlaceholderDirective, {static: false}) private placeholder: PlaceholderDirective;
...
constructor(private componentResolver: ComponentFactoryResolver) {}
...
public launchSensorEditComponent(id: number) {
    const componentFactory = this.componentResolver.resolveComponentFactory(SensorEditComponent);
    const hostViewContainerRef = this.placeholder.viewContainerRef;
    hostViewContainerRef.clear();
    const sensorEditComponentRef = hostViewContainerRef.createComponent(componentFactory);
    sensorEditComponentRef.instance.sensorId = id;
}
Run Code Online (Sandbox Code Playgroud)

实际的动态组件非常简单,它注册在AppModule的entryComponents部分中。我已将其范围缩小到最低限度,以便了解问题所在:

@Component({
  selector: 'app-sensor-edit',
  templateUrl: './sensor-edit.component.html',
  styleUrls: ['./sensor-edit.component.css']
})
export class SensorEditComponent implements OnInit {
  @Input() sensorId: …
Run Code Online (Sandbox Code Playgroud)

angular-components angular angular-dynamic-components angular-lifecycle-hooks

5
推荐指数
1
解决办法
2596
查看次数

在组件函数中选择角度模板而不是在@Component中添加

我正在 Angular 8 中工作,我有一个组件,我有大约 6 个或更多模板。用户将从界面或某种逻辑中选择使用哪一个,比方说,

if(a==2) use template 'ddd.html'
else user template 'sss.html'
Run Code Online (Sandbox Code Playgroud)

我不想在这里使用它

@Component({
selector: 'app-maindisplay',
  templateUrl: './maindisplay.component.html',
  styleUrls: ['./maindisplay.component.css']
})
Run Code Online (Sandbox Code Playgroud)

我希望它出现在任何函数中,无论是构造函数还是任何其他函数。如果它使用任何子组件或指令类型的逻辑来解决就可以了,我唯一需要的是在该逻辑上选择模板。我通常会将相同的数据传递给所有模板,只有它们的设计会改变。

angular angular-dynamic-components

5
推荐指数
1
解决办法
2134
查看次数

如何在翻译开始之前将 i18n 密钥从父组件传递给子组件?

我正在使用一个输入字段组件,可以使用表单将其嵌入到不同的父组件中。

在输入子组件中,我有一个 i18n 翻译键作为使用插值的变量,我想根据客户的选择从父组件动态生成它。

输入.组件.ts

<div i18n="{{labelTextKey}}">{{labelText}}</div>
<div>
    <input matInput [required]="required" 
                    [name]="name"
                    [(ngModel)]="value" 
                    [type]="type">
</div>
Run Code Online (Sandbox Code Playgroud)

表单.组件.ts

<app-input [labelText]="'Second name'"
           [labelTextKey]="'@@LabelSecondName'"
           [name]="'secondName'"
           [ngModel] = "secondName"
           [type] = "'text'"
</app-input>
Run Code Online (Sandbox Code Playgroud)

问题是,运行应用程序时,翻译发生在将密钥传递给子组件中的变量之前,因此 key/id: 没有翻译@@LabelSecondName

因此,labelText 保留原始语言。我得到的不是翻译,而是一种随机生成的数字,并且由于这些数字作为密钥不存在于XLF(版本 2.0)文件中,因此文本/标签不会被翻译。

错误信息:Missing translation for message "8901569964118207331"

该行为在某种程度上是预期的,因为变量:没有及时labelTextKey获得传递的值: 。@@LabelSecondName

一直在寻找,但无法找到正确的解决方案。这个问题似乎和我的比较接近,但又不完全一样,而且也没有答案。

translation internationalization angular-i18n angular angular-dynamic-components

4
推荐指数
1
解决办法
2349
查看次数

在 Angular 中创建嵌套动态组件

我想知道如何创建嵌套动态组件并维护其父子关系。

例如,我有这样的数据,

- A
--A.1
--A.2
-B
--B.1
-C 
Run Code Online (Sandbox Code Playgroud)

我想创建这样的组件,

<A>
   <A1></A1>
   <A2></A2>
</A>
<B>
   <B1></B1>
</B>
<C></C>
Run Code Online (Sandbox Code Playgroud)

但使用我的代码,我只能创建父组件或子组件。但不是两者兼而有之。

下面是我的代码,

  setRootViewContainerRef(view: ViewContainerRef): void {
    this.rootViewContainer = view;
  }

  createComponent(content: any, type: any) {
 console.log(content);
    if (content.child && content.child.length > 0) {
      content.child.forEach(type => {
        const typeP = this.contentMappings[type.type];
        this.createComponent(type, typeP);
      });
    } else {
      this.renderComp(content,type)
    }
  }

  renderComp(content,type) {
    if (!type) {
      return
    }
    this.componentFactory = this.componentFactoryResolver.resolveComponentFactory(type);
    this.componentReference = this.rootViewContainer.createComponent(this.componentFactory);

    if (this.componentReference.instance.contentOnCreate) {
      this.componentReference.instance.contentOnCreate(content);
    }
  }
Run Code Online (Sandbox Code Playgroud)

通过这段代码,我得到了这个输出。

链接到工作示例StackBlitz

请帮我解决这个问题。 …

javascript typescript angular angular-dynamic-components

3
推荐指数
1
解决办法
3048
查看次数

Angular – 通过提交表单将组件的新实例添加到显示中,动态加载同一组件的多个实例

问题更新链接

\n

问题

\n

I\xe2\x80\x99m 尝试动态加载同一组件的多个实例,当用户提交表单时,新组件将添加/加载到屏幕上。其背后的想法是,用户可以提供表单的详细信息,然后将其显示在所创建的组件的特定实例上。

\n

我最初的想法是拥有某种数据结构,例如键对值的数组或映射,这样当用户提交表单时,我可以将组件的新实例与表单数据一起添加到我的数据结构中。然后 Angular 可以以某种方式显示驻留在数据结构中的组件的每个实例,如下图所示:

\n

在此输入图像描述

\n

需要注意的是,该表单实际上是它自己的独立组件,以模式对话框的形式存在。当按下绿色的“添加状态框”按钮时,将打开此表单对话框,然后用户可以提交表单并(希望)能够使用提交的表单提供的数据创建状态框组件的新实例。

\n

然而这被证明是困难的,目前我\xe2\x80\x99m 在上面的屏幕截图中实现这一点的方法是仅在 app.component.html 中单独显示每个组件它根本不是动态的,并且具有无用户控制:

\n
<app-header></app-header>\n<div class=\'status-box-container\'>\n    <app-status-box></app-status-box> //component I\xe2\x80\x99m trying to display\n    <app-status-box></app-status-box> //component I\xe2\x80\x99m trying to display\n    <app-status-box></app-status-box> //component I\xe2\x80\x99m trying to display\n</div>\n
Run Code Online (Sandbox Code Playgroud)\n

我尝试过的事情

\n

我\xe2\x80\x99已经遵循了一些教程,但是所述教程的结果\xe2\x80\x99t完全不符合我\xe2\x80\x99m的要求,\xe2\x80\x99根本不起作用,或者它\xe2\x80\x99 对我来说太复杂了,无法理解。

\n

首先,我尝试遵循Angular 网站上的官方指南,但这一次仅显示一个组件,并且每 3 秒动态更改其内容,而不是同时显示一个组件的多个实例。

\n

接下来,我尝试从这个现有的堆栈溢出问题中跟踪这个 stackblitz,但我发现这不起作用并且非常复杂,其中大部分我不理解\xe2\x80\x99。尽管它\xe2\x80\x99s非常接近我\xe2\x80\x99m试图实现的目标。

\n

最后,我尝试遵循我发现的 stackblitz,但它\xe2\x80\x99s 并不像我希望的那样动态,因为组件的每个实例都被硬编码到不同的变量中,我也无法让它工作。

\n

观察结果

\n

但我注意到的一件事是,所有三种方法都有两个共同点。首先在app.component.html中,他们使用<ng-container #messageContainer></ng-container><ng-template #messageContainer></ng-template>。据我了解,这是将动态组件加载到 …

forms multiple-instances angular-components angular angular-dynamic-components

3
推荐指数
1
解决办法
4993
查看次数

Angular:如何导入 JitCompilerFactory?

如果我使用AOT编译动态编译将不可能。所以我需要将编译器加载到浏览器。那么如何加载呢?如果我使用

import { JitCompilerFactory } from '@angular/compiler';
Run Code Online (Sandbox Code Playgroud)

但是,导入后JitCompilerFactory出现以下错误:

“在 'angular/compiler' 中找不到导出 'JitCompilerFactory'

那么我现在需要从'angular/platform-browser-dynamic'动态编译中导入它是对的吗?

aot angular angular-compiler angular-dynamic-components

1
推荐指数
1
解决办法
2803
查看次数

如何在 Angular 的 innerHTML 中使用 ng-template

有人可以帮助我,如何在innerHTML 标签中使用ng-template,

Stackblitz 演示:https ://stackblitz.com/edit/angular-xgnnj4

我想做的是,

在组件 HTML 中

<div [innerHTML]="htmlString"><div>
Run Code Online (Sandbox Code Playgroud)

在组件 TS

@ViewChild('dynamicComponent', { static: false, read: ViewContainerRef }) myRef: ViewContainerRef;

htmlString = `<ng-template #dynamicComponent></ng-template>`;

  ngAfterViewInit(): void {
    const factory = this.componentFactoryResolver.resolveComponentFactory(CommentComponent);
    const ref = this.myRef.createComponent(factory);
    ref.changeDetectorRef.detectChanges();
  }
Run Code Online (Sandbox Code Playgroud)

我真的需要以这种方式实现,因为我想从 API 获取 HTML 内容并使用该值动态显示 HTML 内容

当我收到错误时无法读取未定义的属性“createComponent”,但如果我将其放在innerHTML 之外,它可以完美运行

我已经浏览了https://angular.io/guide/dynamic-component-loader但它对我的场景没有帮助

innerhtml angular2-template ng-template angular angular-dynamic-components

0
推荐指数
1
解决办法
2150
查看次数