angular/packages/core/test/render3
JiaLiPassion 4a8d5ae970 fix(core): markDirty() should only mark flags when really scheduling tick. (#39316)
Close #39296

Fix an issue that `markDirty()` will not trigger change detection.

The case is for example we have the following component.

```
export class AppComponent implements OnInit {
  constructor(private router: Router) {}

  ngOnInit() {
    this.router.events
      .pipe(filter((e) => e instanceof NavigationEnd))
      .subscribe(() => ɵmarkDirty(this));
  }
}

export class CounterComponent implements OnInit, OnDestroy {
  ngOnInit() {
    this.countSubject.pipe(takeUntil(this.destroy)).subscribe((count) => {
      this.count = count;
      ɵmarkDirty(this);
    });
  }
```

Then the app navigate from `AppComponent` to `CounterComponent`,
so there are 2 `markDirty()` call at in a row.

The `1st` call is from `AppComponent` when router changed, the
`2nd` call is from `CounterComponent.ngOnInit()`.

And the `markDirty()->scheduleTick()` code look like this

```
function scheduleTick(rootContext, flags) {
    const nothingScheduled = rootContext.flags === 0 /* Empty */;
    rootContext.flags |= flags;
    if (nothingScheduled && rootContext.clean == _CLEAN_PROMISE) {
      rootContext.schedule(() => {
	...
        if (rootContext.flags & RootContextFlags.DetectChanges)
          rootContext.flags &= ~RootContextFlags.DetectChanges;
          tickContext();

        rootContext.clean = _CLEAN_PROMISE;
        ...
      });
```

So in this case, the `1st` markDirty() will
1. set rootContext.flags = 1
2. before `tickContext()`, reset rootContext.flags = 0
3. inside `tickContext()`, it will call `CounterComponent.ngOnint()`,
   so the `2nd` markDirty() is called.
4. and the `2nd` scheduleTick is called, `nothingScheduled` is true,
   but rootContext.clean is not `_CLEAN_PROMISE` yet, since the `1st` markDirty tick
   is still running.
5. So nowhere will reset the `rootContext.flags`.
6. then in the future, any other `markDirty()` call will not trigger the tick, since
   `nothingScheduled` is always false.

So `nothingScheduled` means no tick is scheduled, `rootContext.clean === _CLEAN_PROMISE`
means no tick is running.
So we should set the flags to `rootContext` only when `no tick is scheudled or running`.

PR Close #39316
2020-10-29 16:07:10 -07:00
..
i18n fix(compiler): treat i18n attributes with no bindings as static attributes (#39408) 2020-10-27 13:31:29 -07:00
instructions refactor(core): Consistent use of HEADER_OFFSET (in ɵɵ* instructions only) (#39233) 2020-10-21 18:33:00 -07:00
interfaces refactor(core): Create TNodeType.Text to display full template in TView debug (#39233) 2020-10-21 18:33:00 -07:00
ivy build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
jit build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
perf refactor(core): use relative import paths in micro benchmarks (#39142) 2020-10-14 14:10:13 -07:00
styling_next refactor(core): Ensure that previousOrParentTNode always belongs to current TView. (#38707) 2020-09-28 16:15:58 -04:00
util build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
BUILD.bazel refactor(core): add debug ranges to LViewDebug with matchers (#38359) 2020-08-06 16:58:11 -07:00
change_detection_spec.ts fix(core): markDirty() should only mark flags when really scheduling tick. (#39316) 2020-10-29 16:07:10 -07:00
common_with_def.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
component_ref_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
component_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
di_spec.ts refactor(core): add top 10 runtime error codes (#39188) 2020-10-28 10:05:01 -07:00
domino.d.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
global_utils_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
i18n_debug_spec.ts refactor(core): cleanup i18n/icu data structures (#39233) 2020-10-21 18:33:00 -07:00
imported_renderer2.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
instructions_spec.ts refactor(core): Change TemplateFixture to named parameters (#39233) 2020-10-21 18:32:59 -07:00
integration_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
is_shape_of.ts refactor(core): Replace ExpandoInstructions with HostBindingOpCodes (#39301) 2020-10-22 09:35:48 -07:00
is_shape_of_spec.ts refactor(core): add debug ranges to LViewDebug with matchers (#38359) 2020-08-06 16:58:11 -07:00
jit_environment_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
listeners_spec.ts refactor(core): Consistent use of HEADER_OFFSET (in ɵɵ* instructions only) (#39233) 2020-10-21 18:33:00 -07:00
load_domino.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
matchers.ts refactor(core): cleanup i18n/icu data structures (#39233) 2020-10-21 18:33:00 -07:00
matchers_spec.ts refactor(core): Consistent use of HEADER_OFFSET (in ɵɵ* instructions only) (#39233) 2020-10-21 18:33:00 -07:00
metadata_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
node_selector_matcher_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
perfCounter_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
pipe_spec.ts refactor(core): Change TemplateFixture to named parameters (#39233) 2020-10-21 18:32:59 -07:00
providers_spec.ts test(core): remove code specific to IE 9 and IE 10 (#39090) 2020-10-13 15:51:48 -07:00
query_spec.ts refactor(core): Consistent use of HEADER_OFFSET (in ɵɵ* instructions only) (#39233) 2020-10-21 18:33:00 -07:00
render_util.ts refactor(core): Consistent use of HEADER_OFFSET (in ɵɵ* instructions only) (#39233) 2020-10-21 18:33:00 -07:00
renderer_factory_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
testing_spec.ts build: update license headers to reference Google LLC (#37205) 2020-05-26 14:26:58 -04:00
utils.ts refactor(core): Rename debugMatch to matchDebug for consistency (#39233) 2020-10-21 18:33:00 -07:00
view_container_ref_spec.ts refactor(core): Consistent use of HEADER_OFFSET (in ɵɵ* instructions only) (#39233) 2020-10-21 18:33:00 -07:00
view_fixture.ts fix(core): Store ICU state in LView rather than in TView (#39233) 2020-10-21 18:33:00 -07:00
view_utils_spec.ts fix(core): Store ICU state in LView rather than in TView (#39233) 2020-10-21 18:33:00 -07:00