fix(core): ensure ngFor only inserts/moves/removes elements when necessary (#10287)
Closes #9960 Closes #7239 Closes #9672 Closes #9454 Closes #10287
This commit is contained in:
@ -60,6 +60,30 @@ export class AppElement {
|
||||
return result;
|
||||
}
|
||||
|
||||
moveView(view: AppView<any>, currentIndex: number) {
|
||||
var previousIndex = this.nestedViews.indexOf(view);
|
||||
if (view.type === ViewType.COMPONENT) {
|
||||
throw new BaseException(`Component views can't be moved!`);
|
||||
}
|
||||
var nestedViews = this.nestedViews;
|
||||
if (nestedViews == null) {
|
||||
nestedViews = [];
|
||||
this.nestedViews = nestedViews;
|
||||
}
|
||||
ListWrapper.removeAt(nestedViews, previousIndex);
|
||||
ListWrapper.insert(nestedViews, currentIndex, view);
|
||||
var refRenderNode: any /** TODO #9100 */;
|
||||
if (currentIndex > 0) {
|
||||
var prevView = nestedViews[currentIndex - 1];
|
||||
refRenderNode = prevView.lastRootNode;
|
||||
} else {
|
||||
refRenderNode = this.nativeElement;
|
||||
}
|
||||
if (isPresent(refRenderNode)) {
|
||||
view.renderer.attachViewAfter(refRenderNode, view.flatRootNodes);
|
||||
}
|
||||
view.markContentChildAsMoved(this);
|
||||
}
|
||||
|
||||
attachView(view: AppView<any>, viewIndex: number) {
|
||||
if (view.type === ViewType.COMPONENT) {
|
||||
|
@ -288,6 +288,8 @@ export abstract class AppView<T> {
|
||||
}
|
||||
}
|
||||
|
||||
markContentChildAsMoved(renderAppElement: AppElement): void { this.dirtyParentQueriesInternal(); }
|
||||
|
||||
addToContentChildren(renderAppElement: AppElement): void {
|
||||
renderAppElement.parentView.contentChildren.push(this);
|
||||
this.viewContainerElement = renderAppElement;
|
||||
|
@ -99,6 +99,13 @@ export abstract class ViewContainerRef {
|
||||
*/
|
||||
abstract insert(viewRef: ViewRef, index?: number): ViewRef;
|
||||
|
||||
/**
|
||||
* Moves a View identified by a {@link ViewRef} into the container at the specified `index`.
|
||||
*
|
||||
* Returns the inserted {@link ViewRef}.
|
||||
*/
|
||||
abstract move(viewRef: ViewRef, currentIndex: number): ViewRef;
|
||||
|
||||
/**
|
||||
* Returns the index of the View, specified via {@link ViewRef}, within the current container or
|
||||
* `-1` if this container doesn't contain the View.
|
||||
@ -170,6 +177,14 @@ export class ViewContainerRef_ implements ViewContainerRef {
|
||||
return wtfLeave(s, viewRef_);
|
||||
}
|
||||
|
||||
move(viewRef: ViewRef, currentIndex: number): ViewRef {
|
||||
var s = this._insertScope();
|
||||
if (currentIndex == -1) return;
|
||||
var viewRef_ = <ViewRef_<any>>viewRef;
|
||||
this._element.moveView(viewRef_.internalView, currentIndex);
|
||||
return wtfLeave(s, viewRef_);
|
||||
}
|
||||
|
||||
indexOf(viewRef: ViewRef): number {
|
||||
return ListWrapper.indexOf(this._element.nestedViews, (<ViewRef_<any>>viewRef).internalView);
|
||||
}
|
||||
|
Reference in New Issue
Block a user