我想在视图中交换动态放置的组件的位置。
即。我已经动态创建了id = 1和2的组件,如图所示。
现在我需要交换两个组件的位置但是如何?
我知道的一件事(只有理论上)是位置可以通过ViewContainerRef class
对象内的移动方法更改为viewContainerRef.move(componentRef.hostView, index)
。
我尝试了但是位置没有互换。
@ViewChild(ContainerRefDirective) location: ContainerRefDirective;
let componentFactory = this.factoryResolver.resolveComponentFactory(EntryComponent);
let componentRef = this.location.viewContainerRef.createComponent(componentFactory);
let entryComponent: EntryComponent = componentRef.instance;
// lets say counter is variable that increments its value on new component creation.
entryComponent.Id = ++counter;
// move method is being called right after a new component is created and placed.
//this piece of code is in the same method (that is creating the dynamic components)
this.location.viewContainerRef.move(componentRef.hostView, 1);
我已阅读angular.io上的ViewContainerRef文档,并阅读了有关此问题的几乎相同的问题,但无法理解或解决此问题。
答案 0 :(得分:11)
为什么不将两个动态组件绑定到数组? 例如,如果您有“objectA”和“objectB”:
this.renderArray.push(objectA);
..
this.renderArray.push(objectB);
你的html看起来像这样:
<ng-container *ngFor="let renderObject of renderArray">
<<you can reference objectA and objectB by using "renderObject.value" etc.>>
</ng-container>
当你需要交换他们的位置时,你只需要操纵数组,而角度就会照顾其余的:
this.renderArray = this.renderArray.reverse();
它将以新的顺序重新呈现ngFor容器。 请参阅working example here。
答案 1 :(得分:6)
解决了这个问题。
我更改了值,而不是交换组件&#39;地点
即。我替换了值
1 <=> 2
,看起来组件是互换的。
// array to hold the newly created component instances
entryComponents: EntryComponent[] = new Array<EntryComponent>();
然后将新创建的组件推入该数组
let factoryResolver = this.factoryResolver.resolveComponentFactory(EntryComponent);
let componentRef = this.location.viewContainerRef.createComponent(factoryResolver);
this.entryComponents.push(componentRef.instance); // getting components' instances
现在交换值,使组件看起来像互换。
感谢 @ForestG ,了解此建议
答案 2 :(得分:1)
我还没试过这个,但是阅读文档听起来像move
并不是正确的方法。听起来像移动是为了#34;添加&#34;视图的现有组件。
来自detach
的文档:
与insert一起使用以在当前容器中移动View。
基于这一行,我试试......
let ref = this.location.viewContainerRef;
ref.detach(ref.indexOf(componentRef.hostView));
ref.insert(componentRef.hostView, 0);
修改强> 我使用Angular的example实时示例创建了一个有效的Dynamic Component Loader。
以下是与问题相关的代码:
// ShaneCoder - don't clear so we get multiple ads to demonstrate move.
// viewContainerRef.clear();
// ShaneCoder - only create 4 ads
if (viewContainerRef.length<4) {
let componentRef = viewContainerRef.createComponent(componentFactory);
(<AdComponent>componentRef.instance).data = adItem.data;
// ShaneCoder ad is inserted at the bottom (no index parameter). Move it up if there are multiple ads.
if (viewContainerRef.length>=1) {
// we're not the first ad
// move new ad to top using detach and insert (the next two lines answer the original question)
viewContainerRef.detach(viewContainerRef.indexOf(componentRef.hostView));
viewContainerRef.insert(componentRef.hostView, 0);
// comment out the previous two lines to see that ads are inserted at the bottom.
}
}
修改2
在发布最后一次修改后,我没有尝试move
。将detach
和insert
切换为move
,然后就可以了。 Example在这里。相关代码:
viewContainerRef.move(componentRef.hostView, 0);
// comment out the previous two lines to see that ads are inserted at the bottom.
现在我想知道你与move
打架的问题是否是零指数。要使组件成为容器视图中的第一个组件,您需要为索引传递零。使它第二次通过一个,依此类推。所以你的代码会改变如下:
this.location.viewContainerRef.move(componentRef.hostView, 0);