From 06fc42bc445650be3d3981f2b34378ea4ae6ff4e Mon Sep 17 00:00:00 2001 From: Tobias Bosch Date: Mon, 13 Mar 2017 11:12:13 -0700 Subject: [PATCH] =?UTF-8?q?fix(core):=20don=E2=80=99t=20throw=20if=20queri?= =?UTF-8?q?es=20change=20during=20change=20detection.?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Throwing on query changes would be a breaking change compared to v2. Also discovers a bug with querying manually projected content, see #15117. Related to #14748 Closes #14925 --- packages/core/src/view/view.ts | 6 ++-- .../test/linker/query_integration_spec.ts | 23 ++++++++++++++ packages/core/test/view/query_spec.ts | 31 ------------------- 3 files changed, 25 insertions(+), 35 deletions(-) diff --git a/packages/core/src/view/view.ts b/packages/core/src/view/view.ts index 4cd51be2d8..aaa117cee9 100644 --- a/packages/core/src/view/view.ts +++ b/packages/core/src/view/view.ts @@ -318,12 +318,10 @@ function createViewNodes(view: ViewData) { export function checkNoChangesView(view: ViewData) { Services.updateDirectives(view, CheckType.CheckNoChanges); execEmbeddedViewsAction(view, ViewAction.CheckNoChanges); - execQueriesAction( - view, NodeFlags.TypeContentQuery, NodeFlags.DynamicQuery, CheckType.CheckNoChanges); Services.updateRenderer(view, CheckType.CheckNoChanges); execComponentViewsAction(view, ViewAction.CheckNoChanges); - execQueriesAction( - view, NodeFlags.TypeViewQuery, NodeFlags.DynamicQuery, CheckType.CheckNoChanges); + // Note: We don't check queries for changes as we didn't do this in v2.x. + // TODO(tbosch): investigate if we can enable the check again in v5.x with a nicer error message. } export function checkAndUpdateView(view: ViewData) { diff --git a/packages/core/test/linker/query_integration_spec.ts b/packages/core/test/linker/query_integration_spec.ts index 0ca0e0f1c2..bac87609bc 100644 --- a/packages/core/test/linker/query_integration_spec.ts +++ b/packages/core/test/linker/query_integration_spec.ts @@ -536,6 +536,29 @@ export function main() { expect(q.query.length).toBe(0); }); + it('should not throw if a content template is queried and created in the view during change detection', + () => { + @Component( + {selector: 'auto-projecting', template: '
'}) + class AutoProjecting { + @ContentChild(TemplateRef) + content: TemplateRef; + + @ContentChildren(TextDirective) + query: QueryList; + } + + TestBed.configureTestingModule({declarations: [AutoProjecting]}); + const template = + '
'; + const view = createTestCmpAndDetectChanges(MyComp0, template); + + const q = view.debugElement.children[0].references['q']; + // This should be 1, but due to + // https://github.com/angular/angular/issues/15117 this is 0. + expect(q.query.length).toBe(0); + }); + }); }); } diff --git a/packages/core/test/view/query_spec.ts b/packages/core/test/view/query_spec.ts index 4417abfc6b..1901b9fd97 100644 --- a/packages/core/test/view/query_spec.ts +++ b/packages/core/test/view/query_spec.ts @@ -369,37 +369,6 @@ export function main() { }); describe('general binding behavior', () => { - it('should checkNoChanges', () => { - const {view} = createAndGetRootNodes(compViewDef([ - elementDef(NodeFlags.None, null, null, 3, 'div'), - ...contentQueryProviders(), - anchorDef(NodeFlags.EmbeddedViews, null, null, 0, null, embeddedViewDef([ - elementDef(NodeFlags.None, null, null, 1, 'div'), - aServiceProvider(), - ])), - ])); - - Services.checkAndUpdateView(view); - Services.checkNoChangesView(view); - - const childView = Services.createEmbeddedView(view, view.def.nodes[3]); - attachEmbeddedView(view, asElementData(view, 3), 0, childView); - - let err: any; - try { - Services.checkNoChangesView(view); - } catch (e) { - err = e; - } - expect(err).toBeTruthy(); - expect(err.message) - .toBe( - `ExpressionChangedAfterItHasBeenCheckedError: Expression has changed after it was checked. Previous value: 'Query 1 not dirty'. Current value: 'Query 1 dirty'.`); - const debugCtx = getDebugContext(err); - expect(debugCtx.view).toBe(view); - expect(debugCtx.nodeIndex).toBe(2); - }); - it('should report debug info on binding errors', () => { class QueryService { set a(value: any) { throw new Error('Test'); }