fix(ivy): queries should be restored when view changes (#25415)

PR Close #25415
This commit is contained in:
Kara Erickson 2018-08-09 14:07:47 -07:00 committed by Ben Lesh
parent 2b128a47b9
commit 409860a4da
3 changed files with 51 additions and 1 deletions

View File

@ -274,6 +274,7 @@ export function enterView(newView: LViewData, host: LElementNode | LViewNode | n
}
viewData = contextViewData = newView;
oldView && (oldView[QUERIES] = currentQueries);
currentQueries = newView && newView[QUERIES];
return oldView;

View File

@ -62,6 +62,9 @@
{
"name": "PublicFeature"
},
{
"name": "QUERIES"
},
{
"name": "RENDERER"
},

View File

@ -11,7 +11,7 @@ import {ElementRef, TemplateRef, ViewContainerRef} from '@angular/core';
import {EventEmitter} from '../..';
import {QUERY_READ_CONTAINER_REF, QUERY_READ_ELEMENT_REF, QUERY_READ_FROM_NODE, QUERY_READ_TEMPLATE_REF, getOrCreateNodeInjectorForNode, getOrCreateTemplateRef} from '../../src/render3/di';
import {AttributeMarker, QueryList, defineComponent, defineDirective, detectChanges, injectViewContainerRef} from '../../src/render3/index';
import {AttributeMarker, QueryList, defineComponent, defineDirective, detectChanges, injectTemplateRef, injectViewContainerRef} from '../../src/render3/index';
import {bind, container, containerRefreshEnd, containerRefreshStart, element, elementContainerEnd, elementContainerStart, elementEnd, elementProperty, elementStart, embeddedViewEnd, embeddedViewStart, load, loadDirective, loadElement, loadQueryList, registerContentQuery} from '../../src/render3/instructions';
import {RenderFlags} from '../../src/render3/interfaces/definition';
import {query, queryRefresh} from '../../src/render3/query';
@ -1780,6 +1780,52 @@ describe('query', () => {
});
});
it('should restore queries if view changes', () => {
class SomeDir {
constructor(public vcr: ViewContainerRef, public temp: TemplateRef<any>) {
this.vcr.createEmbeddedView(this.temp);
}
static ngDirectiveDef = defineDirective({
type: SomeDir,
selectors: [['', 'someDir', '']],
factory: () => new SomeDir(injectViewContainerRef(), injectTemplateRef())
});
}
function template(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
element(0, 'div');
}
}
/**
* <div *someDir></div>
* <div #foo></div>
*/
const AppComponent = createComponent(
'app',
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
container(1, template, null, [AttributeMarker.SelectOnly, 'someDir']);
element(2, 'div', null, ['foo', '']);
}
},
[SomeDir], [],
function(rf: RenderFlags, ctx: any) {
if (rf & RenderFlags.Create) {
query(0, ['foo'], true, QUERY_READ_FROM_NODE);
}
if (rf & RenderFlags.Update) {
let tmp: any;
queryRefresh(tmp = load<QueryList<any>>(0)) && (ctx.query = tmp as QueryList<any>);
}
});
const fixture = new ComponentFixture(AppComponent);
expect(fixture.component.query.length).toBe(1);
});
describe('content', () => {
let withContentInstance: WithContentDirective|null;
let shallowCompInstance: ShallowComp|null;