Insert / Detach ViewRefs between multiple ViewContainerRefs

Words
402
Reading
2 min
Listen
Play
9y

I submitted a bug report and a feature request on the link below:
https://github.com/angular/angular/issues/20824
Github issue can be found here:

The bug occurs when you try to detach * attach items between ViewContainers in angular.
The bug is caused by a missing reparenting code in the angular core. I was not sure the nature of the problem it might have been inteded so that's why it is also a feature request.

The Bug / Current behavior

We are unable to detach a ViewRef from ViewContainerRef A and attach it to a different ViewContainerRef B

Insert / Detaching doesn't trigger change detection on both ViewContainers.
Using @ContentChildren fails to update changes properly.

Expected behavior

I would like to be able to detach a ViewRef and attach it to a new ViewContainer without recreating the components inside the view. This should work without any issues.

Minimal reproduction of the problem with instructions

https://stackblitz.com/edit/angular-gitter-couoxk?file=app%2Ftest.ts

Manual parent attachment, interaction with underlying dom api is required. Uncomment the code in test.ts LINE 118 to fix to see a workaround & expected behavior.

The provided attachment logic seems to be missing from angular core located here:
https://github.com/angular/angular/blob/5.1.x/packages/core/src/view/refs.ts#L192

What is the motivation / use case for changing the behavior?

I have created a multi drag & drop library in angular, and this bug prevented me using the built in *ngFor due to errors being printed out in the console. Fixing this would help fellow developers to implement such a drag & drop without a hassle and without digging through the angular core codebase.

This would allow to implement Drag & Drop that doesn't recreate the components when an item is dragged over.
Would allow to manipulate dom without using nativeElement, No more worrying about *ngFor trying to find the changes and throwing errors when nodes are missing in dom.

Possible solution

Implement public api for *ngFor for detaching & attaching views between ViewContainers

    attachView(view: ViewRef, index: number)
    {
        let template = (<any>this._template);
        let parentNodeDef = template._def;
        let parent = template._parentView;


        // The Important part!!!
        let viewRef = (<any>view);
        viewRef._view.root = parent.root;
        viewRef._view.parent = parent;
        viewRef._view.renderer = parent.renderer;
        viewRef._view.parentNodeDef = template._def;
        viewRef._view.state = 1 << 0;

        this.ViewContainer.insert(viewRef, index);
    
    }

The bug i caused by a missing marent assignment.l when reattaching the view to a new container. This assignment only occurs when the view is created.

viewRef._view.parent = parent;

Environment


Angular version: 4.x
and 
Angular version: 5.x

Browser:

  • [x] Chrome (desktop) version XX

  • [x] Chrome (Android) version XX

  • [x] Chrome (iOS) version XX

  • [x] Firefox version XX

  • [x] Safari (desktop) version XX

  • [x] Safari (iOS) version XX

  • [x] IE version XX

  • [x] Edge version XX

  • Platform: Mac, linux, Windows



Posted on Utopian.io - Rewarding Open Source Contributors

Insert / Detach ViewRefs between multiple ViewContainerRefs | Ecency