Skip to content

Commit fa29891

Browse files
committed
fix(core): Switch emitDistinctChangesOnlyDefaultValue to true
BREAKING CHANGE: Switching default of `emitDistinctChangesOnlyDefaultValue` which changes the default behavior and may cause some applications which rely on the incorrect behavior to fail. `emitDistinctChangesOnly` flag has also been deprecated and will be removed in a future major release. The previous implementation would fire changes `QueryList.changes.subscribe` whenever the `QueryList` was recomputed. This resulted in an artificially high number of change notifications, as it is possible that recomputing `QueryList` results in the same list. When the `QueryList` gets recomputed is an implementation detail, and it should not be the thing that determines how often change event should fire. Unfortunately, fixing the behavior outright caused too many existing applications to fail. For this reason, Angular considers this fix a breaking fix and has introduced a flag in `@ContentChildren` and `@ViewChildren`, that controls the behavior. ``` export class QueryCompWithStrictChangeEmitParent { @ContentChildren('foo', { // This option is the new default with this change. emitDistinctChangesOnly: true, }) foos!: QueryList<any>; } ``` For backward compatibility before v12 `emitDistinctChangesOnlyDefaultValue` was set to `false. This change changes the default to `true`.
1 parent 153e3a8 commit fa29891

File tree

19 files changed

+86
-86
lines changed

19 files changed

+86
-86
lines changed

packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -570,7 +570,7 @@ A.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: A, selectors: [["",
570570
UndecoratedBase.ɵfac = function UndecoratedBase_Factory(t) { return new (t || UndecoratedBase)(); };
571571
// TRANSPILED
572572
UndecoratedBase.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: UndecoratedBase, viewQuery: function UndecoratedBase_Query(rf, ctx) { if (rf & 1) {
573-
ɵngcc0.ɵɵviewQuery(_c0, 3);
573+
ɵngcc0.ɵɵviewQuery(_c0, 7);
574574
} if (rf & 2) {
575575
let _t;
576576
ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx.test = _t.first);

packages/compiler-cli/src/ngtsc/annotations/src/directive.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -605,7 +605,7 @@ export function extractQueryMetadata(
605605
if (typeof emitDistinctChangesOnlyValue !== 'boolean') {
606606
throw createValueHasWrongTypeError(
607607
emitDistinctChangesOnlyExpr, emitDistinctChangesOnlyValue,
608-
`@${name} options.emitDistinctChangesOnlys must be a boolean`);
608+
`@${name} options.emitDistinctChangesOnly must be a boolean`);
609609
}
610610
emitDistinctChangesOnly = emitDistinctChangesOnlyValue;
611611
}

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/GOLDEN_PARTIAL.js

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ import * as i0 from "@angular/core";
3232
export class ViewQueryComponent {
3333
}
3434
ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); };
35-
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: `
35+
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: `
3636
<div someDir></div>
3737
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
3838
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{
@@ -86,7 +86,7 @@ import * as i0 from "@angular/core";
8686
export class ViewQueryComponent {
8787
}
8888
ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); };
89-
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: `
89+
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: `
9090
<div #myRef></div>
9191
<div #myRef1></div>
9292
`, isInline: true });
@@ -166,7 +166,7 @@ import * as i0 from "@angular/core";
166166
export class ViewQueryComponent {
167167
}
168168
ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); };
169-
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: `
169+
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: `
170170
<div someDir></div>
171171
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
172172
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{
@@ -246,7 +246,7 @@ import * as i0 from "@angular/core";
246246
export class ViewQueryComponent {
247247
}
248248
ViewQueryComponent.ɵfac = function ViewQueryComponent_Factory(t) { return new (t || ViewQueryComponent)(); };
249-
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: `
249+
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: `
250250
<div someDir></div>
251251
<div #myRef></div>
252252
<div #myRef1></div>
@@ -336,7 +336,7 @@ import * as i0 from "@angular/core";
336336
export class ContentQueryComponent {
337337
}
338338
ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); };
339-
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: `
339+
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: `
340340
<div><ng-content></ng-content></div>
341341
`, isInline: true });
342342
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContentQueryComponent, [{
@@ -413,7 +413,7 @@ import * as i0 from "@angular/core";
413413
export class ContentQueryComponent {
414414
}
415415
ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); };
416-
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: `
416+
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: `
417417
<div #myRef></div>
418418
<div #myRef1></div>
419419
`, isInline: true });
@@ -493,7 +493,7 @@ import * as i0 from "@angular/core";
493493
export class ContentQueryComponent {
494494
}
495495
ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); };
496-
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: `
496+
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: `
497497
<div><ng-content></ng-content></div>
498498
`, isInline: true });
499499
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContentQueryComponent, [{
@@ -596,7 +596,7 @@ import * as i0 from "@angular/core";
596596
export class ContentQueryComponent {
597597
}
598598
ContentQueryComponent.ɵfac = function ContentQueryComponent_Factory(t) { return new (t || ContentQueryComponent)(); };
599-
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: `
599+
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: `
600600
<div someDir></div>
601601
<div #myRef></div>
602602
<div #myRef1></div>

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_directive.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
33
selectors: [["content-query-component"]],
44
contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) {
55
if (rf & 1) {
6-
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 1);
7-
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 0);
6+
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 5);
7+
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 4);
88
}
99
if (rf & 2) {
1010
let $tmp$;

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_for_local_ref.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
55
// ...
66
contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) {
77
if (rf & 1) {
8-
$r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 1);
9-
$r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 0);
8+
$r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 5);
9+
$r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 4);
1010
}
1111
if (rf & 2) {
1212
let $tmp$;

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/content_query_read_token.js

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
55
// ...
66
contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) {
77
if (rf & 1) {
8-
$r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 1, TemplateRef);
9-
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 1, ElementRef);
10-
$r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 0, ElementRef);
11-
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 0, TemplateRef);
8+
$r3$.ɵɵcontentQuery(dirIndex, $e0_attrs$, 5, TemplateRef);
9+
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 5, ElementRef);
10+
$r3$.ɵɵcontentQuery(dirIndex, $e1_attrs$, 4, ElementRef);
11+
$r3$.ɵɵcontentQuery(dirIndex, SomeDirective, 4, TemplateRef);
1212
}
1313
if (rf & 2) {
1414
let $tmp$;

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_content_query.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ ContentQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
44
contentQueries: function ContentQueryComponent_ContentQueries(rf, ctx, dirIndex) {
55
if (rf & 1) {
66
$r3$.ɵɵcontentQuery(
7-
dirIndex, SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__);
8-
$r3$.ɵɵcontentQuery(dirIndex, $ref0$, 1);
7+
dirIndex, SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__|__QueryFlags.emitDistinctChangesOnly__);
8+
$r3$.ɵɵcontentQuery(dirIndex, $ref0$, 5);
99
}
1010
if (rf & 2) {
1111
let $tmp$;

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/static_view_query.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ ViewQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
55
selectors: [["view-query-component"]],
66
viewQuery: function ViewQueryComponent_Query(rf, ctx) {
77
if (rf & 1) {
8-
$r3$.ɵɵviewQuery(SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__);
9-
$r3$.ɵɵviewQuery($refs$, 1);
8+
$r3$.ɵɵviewQuery(SomeDirective, __QueryFlags.isStatic__|__QueryFlags.descendants__|__QueryFlags.emitDistinctChangesOnly__);
9+
$r3$.ɵɵviewQuery($refs$, 5);
1010
}
1111
if (rf & 2) {
1212
let $tmp$;

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_directive.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ ViewQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
33
selectors: [["view-query-component"]],
44
viewQuery: function ViewQueryComponent_Query(rf, ctx) {
55
if (rf & 1) {
6-
$r3$.ɵɵviewQuery(SomeDirective, 1);
7-
$r3$.ɵɵviewQuery(SomeDirective, 1);
6+
$r3$.ɵɵviewQuery(SomeDirective, 5);
7+
$r3$.ɵɵviewQuery(SomeDirective, 5);
88
}
99
if (rf & 2) {
1010
let $tmp$;

packages/compiler-cli/test/compliance/test_cases/r3_compiler_compliance/components_and_directives/queries/view_query_for_local_ref.js

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ ViewQueryComponent.ɵcmp = /*@__PURE__*/ $r3$.ɵɵdefineComponent({
55
// ...
66
viewQuery: function ViewQueryComponent_Query(rf, ctx) {
77
if (rf & 1) {
8-
$r3$.ɵɵviewQuery($e0_attrs$, 1);
9-
$r3$.ɵɵviewQuery($e1_attrs$, 1);
8+
$r3$.ɵɵviewQuery($e0_attrs$, 5);
9+
$r3$.ɵɵviewQuery($e1_attrs$, 5);
1010
}
1111
if (rf & 2) {
1212
let $tmp$;

0 commit comments

Comments
 (0)