将角度分量从一个容器移动到另一个容器

时间:2018-02-11 11:38:00

标签: angular

我正在构建一个具有多个值的组件,但不是复制值本身而是复制整个输入组件:

<ng-content>
  <!-- here will be an input component of any type -->
</ng-content>

<button (click)="add()">Add</button>

<div #Container>
</div>

我反对@ContentChild@ViewChild('Container') - 这不是什么大不了的事。但是,我找不到一种平滑的方法将ContentChild表示的输入组件移动到容器,由ViewChild通过单击“添加”按钮来表示。

这是我现在所拥有的解决方法。我通过ElementRef引用它们,然后转向纯DOM操作:

const elContainer: HTMLElement = this._container.nativeElement;
elContainer.appendChild(this._input.nativeElement);

我想知道是否有更好的方法。

更新

@Sreekumar建议使用CDK门户,其目的看起来很常见,但这有一个令人难以置信的开销,看起来(从一个例子),并再次使用DOM:

constructor(
 private componentFactoryResolver: ComponentFactoryResolver,
 private injector: Injector,
 private appRef: ApplicationRef,
) { } 

ngOnInit() {

    // Create a portalHost from a DOM element
    this.portalHost = new DomPortalHost(
      document.querySelector('#pageHeader'),
      this.componentFactoryResolver,
      this.appRef,
      this.injector
    );

    // Locate the component factory for the HeaderComponent
    this.portal = new ComponentPortal(HeaderComponent);

    // Attach portal to host
    this.portalHost.attach(this.portal);
}

1 个答案:

答案 0 :(得分:0)

这是我的解决方案,它不使用DOM。

示例是创建多个动态组件并将它们从一个容器移动到另一个容器。

以下是我们应该做的事情:

  1. 容器A 类型ViewContainerRef;

  2. 容器B 类型ViewContainerRef;

  3. 组件类型ComponentRef; 这是非常重要的,因为我发现,ViewContainerRef方法insert使用ViewRef,你无法从任何其他参考中得到@ViewChild。类型,因此您无法使用@ContentChildprivate _componentFactory: ComponentFactory<SomeComponent>; private _componentRef: ComponentRef<SomeComponent>; @ViewChild('InputContainer', {read: ViewContainerRef}) private _inputContainer: ViewContainerRef; @ViewChild('ItemsContainer', {read: ViewContainerRef}) private _itemsContainer: ViewContainerRef; 然后移动它。所以这里是规则:你要移动的组件应该是动态创建的,因为只有这样你才能得到ComonentRef!你也可以在这里找到一些解释https://stackoverflow.com/a/45339558/3925894

    < / LI>

    以下是步骤:

    <强>变量

    public ngAfterViewInit(): void {
    
      this._componentFactory =
        this._componentFactoryResolver.resolveComponentFactory(SomeComponent);
    
      this._componentRef =
        this._inputContainer.createComponent(this._componentFactory);
    
      this._componentRef.changeDetectorRef.detectChanges();
    
    }
    

    <强>初始化

    private _add() {
    
      const index = this._inputContainer.indexOf(this._componentRef.hostView);
    
      this._inputContainer.detach(index);
    
      this._itemsContainer.insert(this._componentRef.hostView);
    
      this._componentRef =
        this._inputContainer.createComponent(this._componentFactory);
    
      this._componentRef.changeDetectorRef.detectChanges();
    
    }
    

    动态创建和移动组件

    ""

    请参阅plunkr http://plnkr.co/edit/2eHE2S8hTKcQ8i7TidBF?p=preview

    这对我有用。你可以看到没有DOM。