diff --git a/aio/content/guide/deprecations.md b/aio/content/guide/deprecations.md index 7c33b7d2b8..7ead16e1e5 100644 --- a/aio/content/guide/deprecations.md +++ b/aio/content/guide/deprecations.md @@ -95,6 +95,7 @@ Tip: In the [API reference section](api) of this doc site, deprecated APIs are i | [`ANALYZE_FOR_ENTRY_COMPONENTS`](api/core/ANALYZE_FOR_ENTRY_COMPONENTS) | none | v9 | See [`ANALYZE_FOR_ENTRY_COMPONENTS`](#entryComponents) | | [`WrappedValue`](api/core/WrappedValue) | none | v10 | See [removing `WrappedValue`](#wrapped-value) | | [`async`](api/core/testing/async) | [`waitForAsync`](api/core/testing/waitForAsync) | v11 | The `async` function from `@angular/core/testing` has been renamed to `waitForAsync` in order to avoid confusion with the native JavaScript `async` syntax. The existing function is deprecated and will be removed in a future version. | +[ `ViewChildren.emitDistinctChangesOnly` / `ContentChildren.emitDistinctChangesOnly` | none (was part of [issue #40091](https://github.com/angular/angular/issues/40091)) ] | This is a temporary flag introduced as part of bugfix of [issue #40091](https://github.com/angular/angular/issues/40091) and will be removed. | {@a testing} ### @angular/core/testing diff --git a/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts b/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts index b80b39b3a0..5ea2e0ce07 100644 --- a/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts +++ b/packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts @@ -570,7 +570,7 @@ A.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: A, selectors: [["", UndecoratedBase.ɵfac = function UndecoratedBase_Factory(t) { return new (t || UndecoratedBase)(); }; // TRANSPILED UndecoratedBase.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: UndecoratedBase, viewQuery: function UndecoratedBase_Query(rf, ctx) { if (rf & 1) { - ɵngcc0.ɵɵviewQuery(_c0, 3); + ɵngcc0.ɵɵviewQuery(_c0, 7); } if (rf & 2) { let _t; ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx.test = _t.first); diff --git a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts index 52f5a8b2bb..623935e23d 100644 --- a/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts +++ b/packages/compiler-cli/src/ngtsc/annotations/src/directive.ts @@ -605,7 +605,7 @@ export function extractQueryMetadata( if (typeof emitDistinctChangesOnlyValue !== 'boolean') { throw createValueHasWrongTypeError( emitDistinctChangesOnlyExpr, emitDistinctChangesOnlyValue, - `@${name} options.emitDistinctChangesOnlys must be a boolean`); + `@${name} options.emitDistinctChangesOnly must be a boolean`); } emitDistinctChangesOnly = emitDistinctChangesOnlyValue; } diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js index 611b733f93..8f49e5621a 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js @@ -32,7 +32,7 @@ import * as i0 from "@angular/core"; export class ViewQueryComponent { } ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); }; -ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true }, { propertyName: "someDirs", predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true }], ngImport: i0, template: ` +ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true }, { propertyName: "someDirs", predicate: SomeDirective, descendants: true }], ngImport: i0, template: `
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{ @@ -88,7 +88,7 @@ import * as i0 from "@angular/core"; export class ViewQueryComponent { } ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); }; -ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], emitDistinctChangesOnly: false, descendants: true }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"], emitDistinctChangesOnly: false, descendants: true }], ngImport: i0, template: ` +ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], descendants: true }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"], descendants: true }], ngImport: i0, template: `
`, isInline: true }); @@ -170,7 +170,7 @@ import * as i0 from "@angular/core"; export class ViewQueryComponent { } ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); }; -ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true, static: true }, { propertyName: "foo", first: true, predicate: ["foo"], emitDistinctChangesOnly: false, descendants: true }], ngImport: i0, template: ` +ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true, static: true }, { propertyName: "foo", first: true, predicate: ["foo"], descendants: true }], ngImport: i0, template: `
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{ @@ -252,7 +252,7 @@ import * as i0 from "@angular/core"; export class ViewQueryComponent { } ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); }; -ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], emitDistinctChangesOnly: false, descendants: true, read: TemplateRef }, { propertyName: "someDir", first: true, predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true, read: ElementRef }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"], emitDistinctChangesOnly: false, descendants: true, read: ElementRef }, { propertyName: "someDirs", predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true, read: TemplateRef }], ngImport: i0, template: ` +ViewQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ViewQueryComponent, selector: "view-query-component", viewQueries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], descendants: true, read: TemplateRef }, { propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true, read: ElementRef }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"], descendants: true, read: ElementRef }, { propertyName: "someDirs", predicate: SomeDirective, descendants: true, read: TemplateRef }], ngImport: i0, template: `
@@ -344,7 +344,7 @@ import * as i0 from "@angular/core"; export class ContentQueryComponent { } ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); }; -ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true }, { propertyName: "someDirList", predicate: SomeDirective, emitDistinctChangesOnly: false }], ngImport: i0, template: ` +ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true }, { propertyName: "someDirList", predicate: SomeDirective }], ngImport: i0, template: `
`, isInline: true }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContentQueryComponent, [{ @@ -423,7 +423,7 @@ import * as i0 from "@angular/core"; export class ContentQueryComponent { } ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); }; -ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], emitDistinctChangesOnly: false, descendants: true }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"], emitDistinctChangesOnly: false }], ngImport: i0, template: ` +ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], descendants: true }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"] }], ngImport: i0, template: `
`, isInline: true }); @@ -505,7 +505,7 @@ import * as i0 from "@angular/core"; export class ContentQueryComponent { } ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); }; -ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true, static: true }, { propertyName: "foo", first: true, predicate: ["foo"], emitDistinctChangesOnly: false, descendants: true }], ngImport: i0, template: ` +ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true, static: true }, { propertyName: "foo", first: true, predicate: ["foo"], descendants: true }], ngImport: i0, template: `
`, isInline: true }); (function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContentQueryComponent, [{ @@ -610,7 +610,7 @@ import * as i0 from "@angular/core"; export class ContentQueryComponent { } ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); }; -ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], emitDistinctChangesOnly: false, descendants: true, read: TemplateRef }, { propertyName: "someDir", first: true, predicate: SomeDirective, emitDistinctChangesOnly: false, descendants: true, read: ElementRef }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"], emitDistinctChangesOnly: false, read: ElementRef }, { propertyName: "someDirs", predicate: SomeDirective, emitDistinctChangesOnly: false, read: TemplateRef }], ngImport: i0, template: ` +ContentQueryComponent.ɵcmp = i0.ɵɵngDeclareComponent({ version: "0.0.0-PLACEHOLDER", type: ContentQueryComponent, selector: "content-query-component", queries: [{ propertyName: "myRef", first: true, predicate: ["myRef"], descendants: true, read: TemplateRef }, { propertyName: "someDir", first: true, predicate: SomeDirective, descendants: true, read: ElementRef }, { propertyName: "myRefs", predicate: ["myRef1, myRef2, myRef3"], read: ElementRef }, { propertyName: "someDirs", predicate: SomeDirective, read: TemplateRef }], ngImport: i0, template: `
diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_directive.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_directive.js index a06fbaeeaf..d0c83d7933 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_directive.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_directive.js @@ -3,8 +3,8 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ selectors: [["content-query-component"]], contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 1); - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 0); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 5); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 4); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_local_ref.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_local_ref.js index e4a8fa784f..3a78c30a1b 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_local_ref.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_local_ref.js @@ -5,8 +5,8 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ // ... contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { - $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 1); - $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 0); + $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 5); + $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 4); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_read_token.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_read_token.js index 654977fd1a..6de5bc94e3 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_read_token.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_read_token.js @@ -5,10 +5,10 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ // ... contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { - $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 1, TemplateRef); - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 1, ElementRef); - $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 0, ElementRef); - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 0, TemplateRef); + $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 5, TemplateRef); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 5, ElementRef); + $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 4, ElementRef); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 4, TemplateRef); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_content_query.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_content_query.js index 92e99edfd6..051d73112e 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_content_query.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_content_query.js @@ -4,8 +4,8 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { $r3$.ɵɵcontentQuery( - dirIndex, SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__); - $r3$.ɵɵcontentQuery(dirIndex, $ref0$, 1); + dirIndex, SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__|__QueryFlags.emitDistinctChangesOnly__); + $r3$.ɵɵcontentQuery(dirIndex, $ref0$, 5); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_view_query.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_view_query.js index 878e33d922..36c7118540 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_view_query.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_view_query.js @@ -5,8 +5,8 @@ ViewQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ selectors: [["view-query-component"]], viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery(SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__); - $r3$.ɵɵviewQuery($refs$, 1); + $r3$.ɵɵviewQuery(SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__|__QueryFlags.emitDistinctChangesOnly__); + $r3$.ɵɵviewQuery($refs$, 5); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_directive.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_directive.js index c674a30fc5..13502a9a5a 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_directive.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_directive.js @@ -3,8 +3,8 @@ ViewQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ selectors: [["view-query-component"]], viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery(SomeDirective, 1); - $r3$.ɵɵviewQuery(SomeDirective, 1); + $r3$.ɵɵviewQuery(SomeDirective, 5); + $r3$.ɵɵviewQuery(SomeDirective, 5); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_local_ref.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_local_ref.js index a2b233cf80..d8770b0d9b 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_local_ref.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_local_ref.js @@ -5,8 +5,8 @@ ViewQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ // ... viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery($e0_attrs$, 1); - $r3$.ɵɵviewQuery($e1_attrs$, 1); + $r3$.ɵɵviewQuery($e0_attrs$, 5); + $r3$.ɵɵviewQuery($e1_attrs$, 5); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_read_token.js b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_read_token.js index 2e28dd0f0e..247b2fd807 100644 --- a/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_read_token.js +++ b/packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_read_token.js @@ -5,10 +5,10 @@ ViewQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({ // ... viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery($e0_attrs$, 1, TemplateRef); - $r3$.ɵɵviewQuery(SomeDirective, 1, ElementRef); - $r3$.ɵɵviewQuery($e1_attrs$, 1, ElementRef); - $r3$.ɵɵviewQuery(SomeDirective, 1, TemplateRef); + $r3$.ɵɵviewQuery($e0_attrs$, 5, TemplateRef); + $r3$.ɵɵviewQuery(SomeDirective, 5, ElementRef); + $r3$.ɵɵviewQuery($e1_attrs$, 5, ElementRef); + $r3$.ɵɵviewQuery(SomeDirective, 5, TemplateRef); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts b/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts index 50f0b4854d..c2d68d83d3 100644 --- a/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts +++ b/packages/compiler-cli/test/compliance_old/r3_compiler_compliance_spec.ts @@ -1636,8 +1636,8 @@ describe('compiler compliance', () => { selectors: [["view-query-component"]], viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery(SomeDirective, 1); - $r3$.ɵɵviewQuery(SomeDirective, 1); + $r3$.ɵɵviewQuery(SomeDirective, 5); + $r3$.ɵɵviewQuery(SomeDirective, 5); } if (rf & 2) { let $tmp$; @@ -1695,8 +1695,8 @@ describe('compiler compliance', () => { … viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery($e0_attrs$, 1); - $r3$.ɵɵviewQuery($e1_attrs$, 1); + $r3$.ɵɵviewQuery($e0_attrs$, 5); + $r3$.ɵɵviewQuery($e1_attrs$, 5); } if (rf & 2) { let $tmp$; @@ -1746,8 +1746,8 @@ describe('compiler compliance', () => { selectors: [["view-query-component"]], viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery(SomeDirective, 3); - $r3$.ɵɵviewQuery($refs$, 1); + $r3$.ɵɵviewQuery(SomeDirective, 7); + $r3$.ɵɵviewQuery($refs$, 5); } if (rf & 2) { let $tmp$; @@ -1810,10 +1810,10 @@ describe('compiler compliance', () => { … viewQuery: function ViewQueryComponent_Query(rf, ctx) { if (rf & 1) { - $r3$.ɵɵviewQuery($e0_attrs$, 1, TemplateRef); - $r3$.ɵɵviewQuery(SomeDirective, 1, ElementRef); - $r3$.ɵɵviewQuery($e1_attrs$, 1, ElementRef); - $r3$.ɵɵviewQuery(SomeDirective, 1, TemplateRef); + $r3$.ɵɵviewQuery($e0_attrs$, 5, TemplateRef); + $r3$.ɵɵviewQuery(SomeDirective, 5, ElementRef); + $r3$.ɵɵviewQuery($e1_attrs$, 5, ElementRef); + $r3$.ɵɵviewQuery(SomeDirective, 5, TemplateRef); } if (rf & 2) { let $tmp$; @@ -1873,8 +1873,8 @@ describe('compiler compliance', () => { selectors: [["content-query-component"]], contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 1); - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 0); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 5); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 4); } if (rf & 2) { let $tmp$; @@ -1933,8 +1933,8 @@ describe('compiler compliance', () => { … contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { - $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 1); - $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 0); + $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 5); + $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 4); } if (rf & 2) { let $tmp$; @@ -1992,8 +1992,8 @@ describe('compiler compliance', () => { selectors: [["content-query-component"]], contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 3); - $r3$.ɵɵcontentQuery(dirIndex, $ref0$, 1); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 7); + $r3$.ɵɵcontentQuery(dirIndex, $ref0$, 5); } if (rf & 2) { let $tmp$; @@ -2057,10 +2057,10 @@ describe('compiler compliance', () => { … contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) { if (rf & 1) { - $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 1, TemplateRef); - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 1, ElementRef); - $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 0, ElementRef); - $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 0, TemplateRef); + $r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 5, TemplateRef); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 5, ElementRef); + $r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 4, ElementRef); + $r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 4, TemplateRef); } if (rf & 2) { let $tmp$; diff --git a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts index 8ccdfd27ea..9ad05bbc82 100644 --- a/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts +++ b/packages/compiler-cli/test/ngtsc/ngtsc_spec.ts @@ -3133,10 +3133,10 @@ function allTests(os: string) { expect(jsContents).toMatch(varRegExp('test1')); expect(jsContents).toMatch(varRegExp('test2')); expect(jsContents).toMatch(varRegExp('accessor')); - // match `i0.ɵɵcontentQuery(dirIndex, _c1, 1, TemplateRef)` - expect(jsContents).toMatch(contentQueryRegExp('\\w+', 1, 'TemplateRef')); - // match `i0.ɵɵviewQuery(_c2, 1, null)` - expect(jsContents).toMatch(viewQueryRegExp('\\w+', 1)); + // match `i0.ɵɵcontentQuery(dirIndex, _c1, 5, TemplateRef)` + expect(jsContents).toMatch(contentQueryRegExp('\\w+', 5, 'TemplateRef')); + // match `i0.ɵɵviewQuery(_c2, 5, null)` + expect(jsContents).toMatch(viewQueryRegExp('\\w+', 5)); }); it('should generate queries for directives', () => { @@ -3165,14 +3165,14 @@ function allTests(os: string) { expect(jsContents).toMatch(varRegExp('test1')); expect(jsContents).toMatch(varRegExp('test2')); expect(jsContents).toMatch(varRegExp('accessor')); - // match `i0.ɵɵcontentQuery(dirIndex, _c1, 1, TemplateRef)` - expect(jsContents).toMatch(contentQueryRegExp('\\w+', 1, 'TemplateRef')); + // match `i0.ɵɵcontentQuery(dirIndex, _c1, 5, TemplateRef)` + expect(jsContents).toMatch(contentQueryRegExp('\\w+', 5, 'TemplateRef')); - // match `i0.ɵɵviewQuery(_c2, 1)` + // match `i0.ɵɵviewQuery(_c2, 5)` // Note that while ViewQuery doesn't necessarily make sense on a directive, // because it doesn't have a view, we still need to handle it because a component // could extend the directive. - expect(jsContents).toMatch(viewQueryRegExp('\\w+', 1)); + expect(jsContents).toMatch(viewQueryRegExp('\\w+', 5)); }); it('should handle queries that use forwardRef', () => { @@ -3194,13 +3194,13 @@ function allTests(os: string) { env.driveMain(); const jsContents = env.getContents('test.js'); - // match `i0.ɵɵcontentQuery(dirIndex, TemplateRef, 1, null)` - expect(jsContents).toMatch(contentQueryRegExp('TemplateRef', 1)); - // match `i0.ɵɵcontentQuery(dirIndex, ViewContainerRef, 1, null)` - expect(jsContents).toMatch(contentQueryRegExp('ViewContainerRef', 1)); - // match `i0.ɵɵcontentQuery(dirIndex, _c0, 1, null)` + // match `i0.ɵɵcontentQuery(dirIndex, TemplateRef, 5, null)` + expect(jsContents).toMatch(contentQueryRegExp('TemplateRef', 5)); + // match `i0.ɵɵcontentQuery(dirIndex, ViewContainerRef, 5, null)` + expect(jsContents).toMatch(contentQueryRegExp('ViewContainerRef', 5)); + // match `i0.ɵɵcontentQuery(dirIndex, _c0, 5, null)` expect(jsContents).toContain('_c0 = ["parens"];'); - expect(jsContents).toMatch(contentQueryRegExp('_c0', 1)); + expect(jsContents).toMatch(contentQueryRegExp('_c0', 5)); }); it('should handle queries that use an InjectionToken', () => { @@ -3221,10 +3221,10 @@ function allTests(os: string) { env.driveMain(); const jsContents = env.getContents('test.js'); - // match `i0.ɵɵviewQuery(TOKEN, 1, null)` - expect(jsContents).toMatch(viewQueryRegExp('TOKEN', 1)); - // match `i0.ɵɵcontentQuery(dirIndex, TOKEN, 1, null)` - expect(jsContents).toMatch(contentQueryRegExp('TOKEN', 1)); + // match `i0.ɵɵviewQuery(TOKEN, 5, null)` + expect(jsContents).toMatch(viewQueryRegExp('TOKEN', 5)); + // match `i0.ɵɵcontentQuery(dirIndex, TOKEN, 5, null)` + expect(jsContents).toMatch(contentQueryRegExp('TOKEN', 5)); }); it('should compile expressions that write keys', () => { diff --git a/packages/compiler/src/core.ts b/packages/compiler/src/core.ts index a588b90165..a0b07718c3 100644 --- a/packages/compiler/src/core.ts +++ b/packages/compiler/src/core.ts @@ -28,9 +28,8 @@ export const createAttribute = makeMetadataFactory('Attribute', (attributeName: string) => ({attributeName})); // Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not -// explicitly set. This value will be changed to `true` in v12. -// TODO(misko): switch the default in v12 to `true`. See: packages/core/src/metadata/di.ts -export const emitDistinctChangesOnlyDefaultValue = false; +// explicitly set. +export const emitDistinctChangesOnlyDefaultValue = true; export interface Query { diff --git a/packages/compiler/src/render3/partial/api.ts b/packages/compiler/src/render3/partial/api.ts index 383827a8e9..d64931985e 100644 --- a/packages/compiler/src/render3/partial/api.ts +++ b/packages/compiler/src/render3/partial/api.ts @@ -237,9 +237,6 @@ export interface R3DeclareQueryMetadata { /** * True to only fire changes if there are underlying changes to the query. */ - // TODO(misko): This will become `true` be default in v12. `QueryList.changes` would fire even if - // no changes to the query list were detected. This is not ideal, as changes should only fire if - // the `QueryList` actually materially changed. emitDistinctChangesOnly?: boolean; /** diff --git a/packages/compiler/src/render3/partial/directive.ts b/packages/compiler/src/render3/partial/directive.ts index 8b5a854585..0947ca46cd 100644 --- a/packages/compiler/src/render3/partial/directive.ts +++ b/packages/compiler/src/render3/partial/directive.ts @@ -87,9 +87,11 @@ function compileQuery(query: R3QueryMetadata): o.LiteralMapExpr { meta.set( 'predicate', Array.isArray(query.predicate) ? asLiteral(query.predicate) : query.predicate); if (!query.emitDistinctChangesOnly) { - // `emitDistinctChangesOnly` is special because in future we expect it to be `true`. For this - // reason the absence should be interpreted as `true`. + // `emitDistinctChangesOnly` is special because we expect it to be `true`. + // Therefore we explicitly emit the field, and explicitly place it only when it's `false`. meta.set('emitDistinctChangesOnly', o.literal(false)); + } else { + // The linker will assume that an absent `emitDistinctChangesOnly` flag is by default `true`. } if (query.descendants) { meta.set('descendants', o.literal(true)); diff --git a/packages/core/src/linker/query_list.ts b/packages/core/src/linker/query_list.ts index c2bdada5ba..26c12e5b24 100644 --- a/packages/core/src/linker/query_list.ts +++ b/packages/core/src/linker/query_list.ts @@ -62,8 +62,7 @@ export class QueryList implements Iterable { /** * @param emitDistinctChangesOnly Whether `QueryList.changes` should fire only when actual change * has occurred. Or if it should fire when query is recomputed. (recomputing could resolve in - * the same result) This is set to `false` for backwards compatibility but will be changed to - * true in v12. + * the same result) */ constructor(private _emitDistinctChangesOnly: boolean = false) { // This function should be declared on the prototype, but doing so there will cause the class diff --git a/packages/core/src/metadata/di.ts b/packages/core/src/metadata/di.ts index e33d78f3bf..1a793bbde4 100644 --- a/packages/core/src/metadata/di.ts +++ b/packages/core/src/metadata/di.ts @@ -107,9 +107,8 @@ export interface Query { } // Stores the default value of `emitDistinctChangesOnly` when the `emitDistinctChangesOnly` is not -// explicitly set. This value will be changed to `true` in v12. -// TODO(misko): switch the default in v12 to `true`. See: packages/compiler/src/core.ts -export const emitDistinctChangesOnlyDefaultValue = false; +// explicitly set. +export const emitDistinctChangesOnlyDefaultValue = true; /** @@ -148,8 +147,10 @@ export interface ContentChildrenDecorator { * * **selector** - The directive type or the name used for querying. * * **descendants** - True to include all descendants, otherwise include only direct children. * * **emitDistinctChangesOnly** - The ` QueryList#changes` observable will emit new values only - * if the QueryList result has changed. The default value will change from `false` to `true` in - * v12. When `false` the `changes` observable might emit even if the QueryList has not changed. + * if the QueryList result has changed. When `false` the `changes` observable might emit even + * if the QueryList has not changed. + * ** Note: *** This config option is **deprecated**, it will be permanently set to `true` and + * removed in future versions of Angular. * * **read** - Used to read a different token from the queried elements. * * @usageNotes @@ -287,8 +288,10 @@ export interface ViewChildrenDecorator { * * **selector** - The directive type or the name used for querying. * * **read** - Used to read a different token from the queried elements. * * **emitDistinctChangesOnly** - The ` QueryList#changes` observable will emit new values only - * if the QueryList result has changed. The default value will change from `false` to `true` in - * v12. When `false` the `changes` observable might emit even if the QueryList has not changed. + * if the QueryList result has changed. When `false` the `changes` observable might emit even + * if the QueryList has not changed. + * ** Note: *** This config option is **deprecated**, it will be permanently set to `true` and + * removed in future versions of Angular. * * @usageNotes * diff --git a/packages/core/test/acceptance/query_spec.ts b/packages/core/test/acceptance/query_spec.ts index 82da5b20e3..97de093d80 100644 --- a/packages/core/test/acceptance/query_spec.ts +++ b/packages/core/test/acceptance/query_spec.ts @@ -1257,11 +1257,8 @@ describe('query logic', () => { * - systematically detach and insert a view - this would result in unnecessary processing * when the previous and new indexes for the move operation are the same; * - detect the situation where the indexes are the same and do no processing in such case. - * - * This tests asserts on the implementation choices done by the VE (detach and insert) so we - * can replicate the same behavior in ivy. */ - it('should notify on changes when a given view is removed and re-inserted at the same index', + it('should NOT notify on changes when a given view is removed and re-inserted at the same index', () => { @Component({ selector: 'test-comp', @@ -1298,7 +1295,7 @@ describe('query logic', () => { vc.move(viewRef, 0); fixture.detectChanges(); expect(queryList.length).toBe(1); - expect(fixture.componentInstance.queryListNotificationCounter).toBe(2); + expect(fixture.componentInstance.queryListNotificationCounter).toBe(1); }); it('should support a mix of content queries from the declaration and embedded view', () => {