将 @Input 作为参数传递 Type 'string' 没有与 type 共有的属性
Pass @Input as Parameters fires Type 'string' has no properties in common with type
我正在创建基于动态选项卡的组件并传递必要的组件属性以通过对象构建组件。
如何将 @Input
作为参数传递,然后将输入与 ComponentFactoryResolver
一起使用并创建输入。
这是保存必要的选项卡组件属性的对象,
tab-item.ts
import { Type, Input } from '@angular/core';
export class TabItem {
componentLoaded = false;
constructor(public title: string, public active: boolean, public component: Type<object>, public inputs: Input[] = []) {
}
}
tab-component.ts
import { Component, OnInit, Input, ComponentFactoryResolver, ComponentFactory, Injector, ApplicationRef, ElementRef } from '@angular/core';
import { TabItem } from 'src/app/models/tab-item';
@Component({
selector: 'app-tab',
template: `
<div class="row">
<div class="col-2">
<ul class="nav flex-column">
<li class="nav-item" *ngFor="let tab of tabItems">
<a class="nav-link" (click)="setActiveTabItem(tab)" [class.active]="tab.active" [id]="tab.title+'-tab'"
data-toggle="tab" [href]="'#' + tab.title" role="tab" [attr.aria-controls]="tab.title"
aria-selected="true">{{tab.title}}</a>
</li>
</ul>
</div>
<div class="col-10">
<div id="tab-container" class="tab-content">
</div>
</div>
</div>`,
styleUrls: ['./tab.component.scss']
})
export class TabComponent implements OnInit {
@Input() tabItems: TabItem[];
componentsCreated: ComponentFactory<object>[] = [];
constructor(private componentFactorResolver: ComponentFactoryResolver, private injector: Injector,
private app: ApplicationRef,
private elementRef: ElementRef) { }
loadTabContent(selectedIndex: number, isHome: boolean = false): void {
const tabItem = this.tabItems[selectedIndex];
const componentFactory =
this.componentFactorResolver.resolveComponentFactory(tabItem.component);
// Assign Inputs
if (tabItem.inputs) {
tabItem.inputs.forEach((item: Input) => {
componentFactory.inputs.push(item);
});
}
const newNode = document.createElement('div');
newNode.id = tabItem.title;
document.getElementById('tab-container').appendChild(newNode);
const ref = componentFactory.create(this.injector, [], newNode);
this.app.attachView(ref.hostView);
}
}
在这里,在上面的代码中,我收到以下错误 componentFactory.inputs.push(item);
Argument of type 'Input' is not assignable to parameter of type '{
propName: string; templateName: string; }'.
Type 'Input' is missing the following properties from type '{
propName: string; templateName: string; }': propName,
templateNamets(2345)
最后,像下面这样创建标签项并从父组件传递它
<app-tab [tabItems]="tabItems"></app-tab>
@Input() header = 'Test';
tabItems = [
new TabItem('Home', true, HomeComponent),
new TabItem('Profile', false, ProfileComponent),
new TabItem('Employee', false, EmployeeComponent, [this.header])
];
这里,错误是,
Type 'string' has no properties in common with type 'Input'.ts(2559)
这是传递输入的正确方法吗?如果是这样,这有什么问题?
根据 ComponentFactory
docs it has an inputs
property 预计 { propName: string; templateName: string; }
的 Array
。
您的问题来自 2 次违规:
在app.component.ts里面你试着考虑@Input
指令为 Input
类型,而您将其设置为 string
!
Inside tab.component.ts 你试图将 Input
作为
ComponentFactory
的类型 inputs
!
我在 Stackblitz 中的更改可能会指导您编写更好的代码。
我做了以下更改。 仍在寻找最佳方法(如果有的话)。
在未指定 Input
类型的情况下对参数使用剩余运算符
import { Type, Input } from '@angular/core';
export class TabItem {
componentLoaded = false;
args;
constructor(public title: string, public active: boolean, public component: Type<object>, ...args) {
}
}
tab-component.ts
loadTabContent(selectedIndex: number, isHome: boolean = false): void {
const tabItem = this.tabItems[selectedIndex];
const componentFactory =
this.componentFactorResolver.resolveComponentFactory(tabItem.component);
const newNode = document.createElement('div');
newNode.id = tabItem.title;
document.getElementById('tab-container').appendChild(newNode);
const ref = componentFactory.create(this.injector, [], newNode);
this.app.attachView(ref.hostView);
if (tabItem.args) {
tabItem.args.forEach((item) => {
Object.keys(item).forEach(key => {
const value = item[key];
ref.instance[key] = value; //Here it works!
});
});
}
}
创建时,这里不需要是Input
类型,一对key:value
就够了
<app-tab [tabItems]="tabItems"></app-tab>
tabItems = [
new TabItem('Home', true, HomeComponent),
new TabItem('Employee', false, EmployeeComponent, {'header': 'Test data'})
];
我正在创建基于动态选项卡的组件并传递必要的组件属性以通过对象构建组件。
如何将 @Input
作为参数传递,然后将输入与 ComponentFactoryResolver
一起使用并创建输入。
这是保存必要的选项卡组件属性的对象,
tab-item.ts
import { Type, Input } from '@angular/core';
export class TabItem {
componentLoaded = false;
constructor(public title: string, public active: boolean, public component: Type<object>, public inputs: Input[] = []) {
}
}
tab-component.ts
import { Component, OnInit, Input, ComponentFactoryResolver, ComponentFactory, Injector, ApplicationRef, ElementRef } from '@angular/core';
import { TabItem } from 'src/app/models/tab-item';
@Component({
selector: 'app-tab',
template: `
<div class="row">
<div class="col-2">
<ul class="nav flex-column">
<li class="nav-item" *ngFor="let tab of tabItems">
<a class="nav-link" (click)="setActiveTabItem(tab)" [class.active]="tab.active" [id]="tab.title+'-tab'"
data-toggle="tab" [href]="'#' + tab.title" role="tab" [attr.aria-controls]="tab.title"
aria-selected="true">{{tab.title}}</a>
</li>
</ul>
</div>
<div class="col-10">
<div id="tab-container" class="tab-content">
</div>
</div>
</div>`,
styleUrls: ['./tab.component.scss']
})
export class TabComponent implements OnInit {
@Input() tabItems: TabItem[];
componentsCreated: ComponentFactory<object>[] = [];
constructor(private componentFactorResolver: ComponentFactoryResolver, private injector: Injector,
private app: ApplicationRef,
private elementRef: ElementRef) { }
loadTabContent(selectedIndex: number, isHome: boolean = false): void {
const tabItem = this.tabItems[selectedIndex];
const componentFactory =
this.componentFactorResolver.resolveComponentFactory(tabItem.component);
// Assign Inputs
if (tabItem.inputs) {
tabItem.inputs.forEach((item: Input) => {
componentFactory.inputs.push(item);
});
}
const newNode = document.createElement('div');
newNode.id = tabItem.title;
document.getElementById('tab-container').appendChild(newNode);
const ref = componentFactory.create(this.injector, [], newNode);
this.app.attachView(ref.hostView);
}
}
在这里,在上面的代码中,我收到以下错误 componentFactory.inputs.push(item);
Argument of type 'Input' is not assignable to parameter of type '{ propName: string; templateName: string; }'.
Type 'Input' is missing the following properties from type '{ propName: string; templateName: string; }': propName, templateNamets(2345)
最后,像下面这样创建标签项并从父组件传递它
<app-tab [tabItems]="tabItems"></app-tab>
@Input() header = 'Test';
tabItems = [
new TabItem('Home', true, HomeComponent),
new TabItem('Profile', false, ProfileComponent),
new TabItem('Employee', false, EmployeeComponent, [this.header])
];
这里,错误是,
Type 'string' has no properties in common with type 'Input'.ts(2559)
这是传递输入的正确方法吗?如果是这样,这有什么问题?
根据 ComponentFactory
docs it has an inputs
property 预计 { propName: string; templateName: string; }
的 Array
。
您的问题来自 2 次违规:
在app.component.ts里面你试着考虑
@Input
指令为Input
类型,而您将其设置为string
!Inside tab.component.ts 你试图将
Input
作为ComponentFactory
的类型inputs
!
我在 Stackblitz 中的更改可能会指导您编写更好的代码。
我做了以下更改。 仍在寻找最佳方法(如果有的话)。
在未指定 Input
类型的情况下对参数使用剩余运算符
import { Type, Input } from '@angular/core';
export class TabItem {
componentLoaded = false;
args;
constructor(public title: string, public active: boolean, public component: Type<object>, ...args) {
}
}
tab-component.ts
loadTabContent(selectedIndex: number, isHome: boolean = false): void {
const tabItem = this.tabItems[selectedIndex];
const componentFactory =
this.componentFactorResolver.resolveComponentFactory(tabItem.component);
const newNode = document.createElement('div');
newNode.id = tabItem.title;
document.getElementById('tab-container').appendChild(newNode);
const ref = componentFactory.create(this.injector, [], newNode);
this.app.attachView(ref.hostView);
if (tabItem.args) {
tabItem.args.forEach((item) => {
Object.keys(item).forEach(key => {
const value = item[key];
ref.instance[key] = value; //Here it works!
});
});
}
}
创建时,这里不需要是Input
类型,一对key:value
就够了
<app-tab [tabItems]="tabItems"></app-tab>
tabItems = [
new TabItem('Home', true, HomeComponent),
new TabItem('Employee', false, EmployeeComponent, {'header': 'Test data'})
];