fix(ivy): sync ViewRefs between multiple ViewContainerRefs (#30985)

Previously, multiple ViewContainerRef instances (obtained by injecting
ViewContainerRef multiple times) each had private state that could be out of
sync with actual LContainer, if views were inserted/removed/queried across
the different instances. In particular each instance had its own array which
tracked ViewRefs inserted via that instance.

This commit moves the ViewRefs array onto the LContainer itself, so that it
can be shared across multiple ViewContainerRef instances. A test is added
that verifies ViewContainerRefs now provide a consistent view of the
container.

FW-1377 #resolve

PR Close #30985
This commit is contained in:
Alex Rickabaugh
2019-06-11 15:59:41 -07:00
committed by Kara Erickson
parent b1664425a9
commit bd3b0564e6
5 changed files with 70 additions and 11 deletions

View File

@ -6,6 +6,8 @@
* found in the LICENSE file at https://angular.io/license
*/
import {ViewRef} from '../../linker/view_ref';
import {TNode} from './node';
import {LQueries} from './query';
import {RComment, RElement} from './renderer';
@ -28,6 +30,7 @@ export const ACTIVE_INDEX = 2;
// PARENT, NEXT, QUERIES and T_HOST are indices 3, 4, 5 and 6.
// As we already have these constants in LView, we don't need to re-create them.
export const NATIVE = 7;
export const VIEW_REFS = 8;
/**
* Size of LContainer's header. Represents the index after which all views in the
@ -35,7 +38,7 @@ export const NATIVE = 7;
* which views are already in the DOM (and don't need to be re-added) and so we can
* remove views from the DOM when they are no longer required.
*/
export const CONTAINER_HEADER_OFFSET = 8;
export const CONTAINER_HEADER_OFFSET = 9;
/**
* The state associated with a container.
@ -99,6 +102,13 @@ export interface LContainer extends Array<any> {
/** The comment element that serves as an anchor for this LContainer. */
readonly[NATIVE]:
RComment; // TODO(misko): remove as this value can be gotten by unwrapping `[HOST]`
/**
* Array of `ViewRef`s used by any `ViewContainerRef`s that point to this container.
*
* This is lazily initialized by `ViewContainerRef` when the first view is inserted.
*/
[VIEW_REFS]: ViewRef[]|null;
}
// Note: This hack is necessary so we don't erroneously get a circular dependency