Closed as not planned
Description
Which @angular/* package(s) are the source of the bug?
core
Is this a regression?
No
Description
Here is a component:
@Component({
selector: 'app-root',
changeDetection: ChangeDetectionStrategy.OnPush,
template: `
<button type="button" (click)="d.toggle()">Toggle</button>
<button type="button" (click)="state = !state">Toggle by binding</button>
<ul class="mt-2">
<li>state = {{ state }}</li>
<li>d.state = {{ d.stateChange | async }}</li>
<li>processing = {{ d.processing | async }}</li>
</ul>
<div #d="myDirective" [(myDirective)]="state"></div>
`,
})
export class AppComponent {
state = false;
}
It uses the following directive:
import { Directive, Input, Output } from '@angular/core';
import { BehaviorSubject } from 'rxjs';
export const createModel = () => {
const state$ = new BehaviorSubject(true);
const processing$ = new BehaviorSubject(false);
const toggle = async (newState = !state$.getValue()): Promise<void> => {
console.log('Beginning toggle, newState = ' + newState);
// Note that uncommenting the following line is a workaround for this issue:
// await Promise.resolve();
processing$.next(true);
state$.next(newState);
await new Promise((resolve) => setTimeout(resolve, 1000));
processing$.next(false);
console.log('Ending toggle, newState = ' + newState);
};
return {
state$,
processing$,
toggle,
};
};
@Directive({
selector: '[myDirective]',
exportAs: 'myDirective',
})
export class MyDirective {
private model = createModel();
@Input('myDirective')
set state(value: boolean) {
this.model.toggle(value);
}
@Output('myDirectiveChange')
stateChange = this.model.state$;
processing = this.model.processing$;
toggle() {
return this.model.toggle();
}
}
When clicking on the "Toggle" button in the component, everything works as expected:
- The first two lines
state
andd.state
have the same boolean value (the opposite of the previous value), and the third line hasprocessing = true
- After 1s, the third line switches back to
processing = false
When clicking on the "Toggle by binding" button, the same toggle
method from the model is triggered, so the same behavior as before would be expected. However, Angular only refreshes the first line (state
) and does not update the d.state
and processing
lines, even though they changed. After 1s, the second line (d.state
) is updated with the correct value and the third line did not change at all (now that the value of processing
is back to false
).
Please provide a link to a minimal reproduction of the bug
https://stackblitz.com/edit/angular-ivy-liytcm?file=src/app/app.component.ts
Please provide the exception or error you saw
There is no error in the console.
Please provide the environment you discovered this bug in (run ng version
)
Angular CLI: 14.0.7
Node: 16.17.1
Package Manager: npm 8.15.0
OS: linux x64
Angular: 14.2.4
... animations, common, compiler, compiler-cli, core, forms
... platform-browser, platform-browser-dynamic, router
Package Version
---------------------------------------------------------
@angular-devkit/architect 0.1402.4
@angular-devkit/build-angular 14.2.4
@angular-devkit/core 14.2.4
@angular-devkit/schematics 14.0.7
@angular/cli 14.0.7
@schematics/angular 14.0.7
rxjs 7.5.7
typescript 4.7.4
Anything else?
No response
Metadata
Metadata
Assignees
Labels
No labels