英文:
Is there a way to pass data between two same level component in Angular using @Input?
问题
dynamic-container.component.html
<h1>Angular中的动态组件</h1>
<ul>
<li (click)="createComponent(productNames.mobile)">手机</li>
<li (click)="createComponent(productNames.laptop)">笔记本电脑</li>
<li (click)="createComponent(productNames.watch)">手表</li>
<li (click)="createComponent(productNames.burger)">汉堡包</li>
<li (click)="createComponent(productNames.ovan)">烤箱</li>
</ul>
<div class="display black-border">
<ng-container #container></ng-container>
</div>
dynamic-container.component.ts
@Component({
selector: 'app-dynamic-container',
templateUrl: './dynamic-container.component.html',
styleUrls: ['./dynamic-container.component.css']
})
export class DynamicContainerComponent implements OnInit {
@ViewChild('container', { read: ViewContainerRef, static: true }) container: ViewContainerRef | any;
componentMap = new Map<string, ComponentRef<any>>();
index = 0;
productNames: any = {
mobile: '手机',
laptop: '笔记本电脑',
watch: '手表',
burger: '汉堡包',
ovan: '烤箱'
};
createComponent(name: string) {
const compType = this.getComponentType(name);
const comp = this.container.createComponent(compType);
let uniqueName = name + ' - ' + this.index.toString();
this.index++;
comp.instance.name = uniqueName;
}
getComponentType(name: string): Type<any> {
let type: Type<any> = MobileComponent;
switch (name) {
case this.productNames.mobile: {
type = MobileComponent;
break;
}
case this.productNames.laptop: {
type = LaptopComponent;
break;
}
case this.productNames.burger: {
type = BurgerComponent;
break;
}
case this.productNames.ovan: {
type = OvanComponent;
break;
}
case this.productNames.watch: {
type = WatchComponent;
break;
}
}
return type;
}
}
在dynamic-container下面,你可以看到一个名为mobile的组件(参考图片)。
在mobile.component.ts中
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-mobile',
templateUrl: './mobile.component.html',
styleUrls: ['./mobile.component.css']
})
export class MobileComponent {
@Input() name: string = '';
}
在mobile.component.html中
<h4>{{name | titlecase}}</h4>
如果你想看app.component.html
<app-dynamic-container></app-dynamic-container>
和app.module.ts
@NgModule({
declarations: [
AppComponent,
DynamicContainerComponent,
MobileComponent,
LaptopComponent,
BurgerComponent,
WatchComponent,
OvanComponent
],
providers: [],
bootstrap: [AppComponent],
imports: [
BrowserModule,
CommonModule
],
exports:[DynamicContainerComponent]
})
export class AppModule { }
我搜索了一下,是否有一种在没有属性绑定的情况下使用@Input的方法,但发现@Input需要**[属性绑定]**,通常在父子组件之间进行。
但你可以看到这里是在两个同级组件之间进行的,即dynamic-container和mobile。
所以,我无法理解它是如何在底层发生的,或者我是否遗漏了某个概念。我在YouTube上找到了这个视频,这是链接 - (https://www.youtube.com/watch?v=GE_lxrbFNtI&t=222s)。有人可以帮助我理解吗?
英文:
Folder structure of the project (for reference)
dynamic-container.component.html
<h1>Dynamic component in angular</h1>
<ul>
<li (click)="createComponent(productNames.mobile)">Mobile</li>
<li (click)="createComponent(productNames.laptop)">Laptop</li>
<li (click)="createComponent(productNames.watch)">Watch</li>
<li (click)="createComponent(productNames.burger)">Burger</li>
<li (click)="createComponent(productNames.ovan)">Ovan</li>
</ul>
<div class="display black-border">
<ng-container #container></ng-container>
</div>
dynamic-container.component.ts
@Component({
selector: 'app-dynamic-container',
templateUrl: './dynamic-container.component.html',
styleUrls: ['./dynamic-container.component.css']
})
export class DynamicContainerComponent implements OnInit{
@ViewChild('container',{read:ViewContainerRef,static:true}) container:ViewContainerRef|any
componentMap=new Map<string,ComponentRef<any>>()
index=0
productNames:any={
mobile:'mobile',
laptop:'laptop',
watch:'watch',
burger:'burger',
ovan:'ovan'
}
createComponent(name:string){
const compType=this.getComponentType(name)
const comp=this.container.createComponent(compType) // comp store the reference returned by the method
let uniqueName=name+' - '+this.index.toString()
this.index++
comp.instance.name=uniqueName // comp has a instance property
}
getComponentType(name:string):Type<any>
{
let type: Type<any>=MobileComponent
switch(name)
{
case this.productNames.mobile:{
type=MobileComponent
break
}
case this.productNames.laptop:{
type=LaptopComponent
break
}
case this.productNames.burger:{
type=BurgerComponent
break
}
case this.productNames.ovan:{
type=OvanComponent
break
}
case this.productNames.watch:{
type=WatchComponent
break
}
}
return type
}
}
Below dynamic-container you can see there is a component called mobile(refer the image).
In mobile.component.ts
import { Component, EventEmitter, Input, Output } from '@angular/core';
@Component({
selector: 'app-mobile',
templateUrl: './mobile.component.html',
styleUrls: ['./mobile.component.css']
})
export class MobileComponent {
@Input() name:string=''
}
In mobile.component.html
<h4>{{name | titlecase}}</h4>
In case you want to see app.component.html
<app-dynamic-container></app-dynamic-container>
and app.module.ts
@NgModule({
declarations: [
AppComponent,
DynamicContainerComponent,
MobileComponent,
LaptopComponent,
BurgerComponent,
WatchComponent,
OvanComponent
],
providers: [],
bootstrap: [AppComponent],
imports: [
BrowserModule,
CommonModule
],
exports:[DynamicContainerComponent]
})
export class AppModule { }
I searched if there is any way of using @Input without property binding but found @Input need [property binding] and is done between parent and child component.
But you can see here it is done between 2 same level components that is dynamic-container and mobile.
So, I am not able to understand how it is happening under the hood or am I missing any concept. I found this in a youtube video here is the link - (https://www.youtube.com/watch?v=GE_lxrbFNtI&t=222s).
Can anyone please help me understand this?
答案1
得分: 1
使用services
在同级组件之间传递数据更好。在那里定义您的变量,然后在两个组件中使用它。
否则,如果您不想使用服务,首先需要使用output
和EventEmitter
在子组件和父组件之间共享数据。一旦在父组件中接收到数据,再将其分享给另一个子组件,使用Input
。
英文:
For passing data between same level component its better to use services
. define your variables there and use it in both components.
otherwise if you don't want to use services, first you need to share data between the child to parent using output
and EventEmitter
. Once received data in parent component share it to another child component using Input
.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论