英文:
In Angular Child created dynamically don't get their @Input updated
问题
I have created a simple demo of my issue HERE.
So I have a parent which have a topics list (just an array of string), this topics list is generated randomly each time we click on the button generate (button which is in the parent)
Then I have a component named child which takes as input the topics list and a title.
When I create this child through the DOM it works as expected. But when I create the exact same child component but programmatically then the topics list is not updated.
So when I create this child through the DOM like this:
<app-child [topicsList]="topicsList" [title]="'Child created from the DOM'"></app-child>
It is working as expected, when I click on generate, the child get the updated topics list and display it. But when I create the exact same child component but programmatically like this:
this.mChildRef = this.mViewContainerRef.createComponent(ChildComponent); this.mChildRef.setInput('topicsList', this.topicsList); this.mChildRef.setInput('title', "Child created dynamically");
then the topics list is not updated. I tried with public variables instead of @Input and set the Inputs like this: this.mChildRef.instance.topicsList = this.topicsList
I also tried to play with: this.mChildRef.changeDetectorRef
I try to get changes through ngOnChanges but this event is fired only at the creation of the child component.
But nothing works...
I have probably missed something but I don't know what, maybe a specific configuration in the component or an extra parameter to pass when I create the component.
Thank you for your help
英文:
I have created a simple demo of my issue HERE.
So I have a parent which have a topics list (just an array of string), this topics list is generated randomly each time we click on the button generate (button which is in the parent)
Then I have a component named child which takes as input the topics list and a title.
When I create this child through the DOM it works as expected. But when I create the exact same child component but programmatically then the topics list is not updated.
So when I create this child through the DOM like this:
<app-child [topicsList]="topicsList" [title]="'Child created from the DOM'"></app-child>
It is working as expected, when I click on generate, the child get the updated topics list and display it. But when I create the exact same child component but programmatically like this:
this.mChildRef = this.mViewContainerRef.createComponent(ChildComponent);
this.mChildRef.setInput('topicsList', this.topicsList);
this.mChildRef.setInput('title', "Child created dynamically");
then the topics list is not updated.
I tried with public variables instead of @Input and set the Inputs like this:
this.mChildRef.instance.topicsList = this.topicsList
I also tried to play with:
this.mChildRef.changeDetectorRef
I try to get changes through ngOnChanges but this event is fired only at the creation of the child component.
But nothing works...
I have probably missed something but I don't know what, maybe a specific configuration in the component or an extra parameter to pass when I create the component.
Thank you for your help
答案1
得分: 1
以下是用于Stack Overflow的答案:
// 创建一个动态子组件的映射
private childComponentsMap: Map<string, ComponentRef<ChildComponent>> = new Map();
// 将子组件添加到映射中
this.childComponentsMap.set('Id' + this.componentId, this.mChildRef);
// 遍历子组件映射并更新主题列表
this.childComponentsMap.forEach((componentRef) => {
componentRef.instance.topicsList = this.topicsList;
});
在提供的代码片段中,childComponentsMap
被创建为一个 Map
,用于存储动态创建的子组件。每个组件都以唯一的标识符('Id' + this.componentId
)作为键,相应的 ComponentRef<ChildComponent>
作为值添加到映射中。
要更新所有子组件的主题列表,您可以使用 forEach
方法遍历 childComponentsMap
。在循环内,您可以访问每个组件引用(componentRef
)并将其 topicsList
属性设置为更新后的 this.topicsList
值。
这种方法允许您维护一个动态创建的子组件的映射,并根据需要轻松更新它们的属性。
希望这有助于解决您的问题。如果您有任何进一步的问题,请随时告诉我!
英文:
Below is the answer you can use for Stack Overflow:
// Create a map of dynamic child components
private childComponentsMap: Map<string, ComponentRef<ChildComponent>> = new Map();
// Add child component to the map
this.childComponentsMap.set('Id' + this.componentId, this.mChildRef);
// Iterate through the child components map and update the topics list
this.childComponentsMap.forEach((componentRef) => {
componentRef.instance.topicsList = this.topicsList;
});
In the provided code snippet, the childComponentsMap
is created as a Map
to store the dynamically created child components. Each component is added to the map using a unique identifier ('Id' + this.componentId
) as the key and the corresponding ComponentRef<ChildComponent>
as the value.
To update the topics list for all the child components, you can iterate through the childComponentsMap
using the forEach
method. Within the loop, you can access each component reference (componentRef
) and set its topicsList
property to the updated this.topicsList
value.
This approach allows you to maintain a map of dynamically created child components and easily update their properties as needed.
I hope this helps to resolve your issue. Let me know if you have any further questions!
答案2
得分: 0
你必须明确更新输入,如果组件是动态创建的。
// 列表更新后
this.mChildRef.setInput('topicsList', this.topicsList);
你也可以做一些巧妙的事情,比如将元素置于原始列表中,该列表已绑定到组件的输入。
this.topicsList.splice(0, 999, ...topicsList);
但要自担风险,因为这可能会导致难以调试的错误,并且不适用于 OnPush 策略。
英文:
you have to explicitly update the input if the component was created dynamically
// after list update
this.mChildRef.setInput('topicsList', this.topicsList);
you could also do something tricky like emplacing elements in the original list that was bound to component input
this.topicsList.splice(0, 999, ...topicsList);
but do it at your risk, because it can cause bugs that are hard to debug and it won't work with OnPush strategy
答案3
得分: 0
If I've right understood, you need to update onGenerateTopicsList method:
onGenerateTopicsList(): void {
// your existing code...
this.mChildRef.setInput('topicsList', this.topicsList);
}
英文:
If I've right understood, you need to update onGenerateTopicsList method:
onGenerateTopicsList(): void {
// your existing code...
this.mChildRef.setInput('topicsList', this.topicsList);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论