Skip to content

Commit

Permalink
fix(core): Switch emitDistinctChangesOnlyDefaultValue to true
Browse files Browse the repository at this point in the history
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`.
  • Loading branch information
mhevery committed Mar 10, 2021
1 parent 153e3a8 commit 0e32b8c
Show file tree
Hide file tree
Showing 20 changed files with 84 additions and 87 deletions.
2 changes: 1 addition & 1 deletion goldens/public-api/core/core.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -172,7 +172,7 @@ export declare interface ContentChildDecorator {
export declare type ContentChildren = Query;

export declare interface ContentChildrenDecorator {
(selector: Type<any> | InjectionToken<unknown> | Function | string, opts?: {
/** @deprecated */ (selector: Type<any> | InjectionToken<unknown> | Function | string, opts?: {
descendants?: boolean;
emitDistinctChangesOnly?: boolean;
read?: any;
Expand Down
2 changes: 1 addition & 1 deletion packages/compiler-cli/ngcc/test/rendering/renderer_spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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: `
<div someDir></div>
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{
Expand Down Expand Up @@ -86,7 +86,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: `
<div #myRef></div>
<div #myRef1></div>
`, isInline: true });
Expand Down Expand Up @@ -166,7 +166,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: `
<div someDir></div>
`, isInline: true, directives: [{ type: i0.forwardRef(function () { return SomeDirective; }), selector: "[someDir]" }] });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ViewQueryComponent, [{
Expand Down Expand Up @@ -246,7 +246,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: `
<div someDir></div>
<div #myRef></div>
<div #myRef1></div>
Expand Down Expand Up @@ -336,7 +336,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: `
<div><ng-content></ng-content></div>
`, isInline: true });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContentQueryComponent, [{
Expand Down Expand Up @@ -413,7 +413,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: `
<div #myRef></div>
<div #myRef1></div>
`, isInline: true });
Expand Down Expand Up @@ -493,7 +493,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: `
<div><ng-content></ng-content></div>
`, isInline: true });
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && i0.ɵsetClassMetadata(ContentQueryComponent, [{
Expand Down Expand Up @@ -596,7 +596,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: `
<div someDir></div>
<div #myRef></div>
<div #myRef1></div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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$;
Expand Down

0 comments on commit 0e32b8c

Please sign in to comment.