_zone.onMicrotaskEmpty:

class ApplicationRef {
    / * *@internal * /
    constructor(_zone, _console, _injector, _exceptionHandler, _componentFactoryResolver, _initStatus) {
        this._zone = _zone;
        this._console = _console;
        this._injector = _injector;
        this._exceptionHandler = _exceptionHandler;
        this._componentFactoryResolver = _componentFactoryResolver;
        this._initStatus = _initStatus;
        / * *@internal * /
        this._bootstrapListeners = [];
        this._views = [];
        this._runningTick = false;
        this._enforceNoNewChanges = false;
        this._stable = true;
        /** * Get a list of component types registered to this application. * This list is populated even before the component is created. */
        this.componentTypes = [];
        /** * Get a list of components registered to this application. */
        this.components = [];
        this._enforceNoNewChanges = isDevMode();
        this._zone.onMicrotaskEmpty.subscribe({
            next: () = > {
                this._zone.run(() = > {
                    this.tick(); }); }});Copy the code

The implementation of the tick method calls the detectChange method of the view:

/** * Invoke this method to explicitly process change detection and its side-effects. * * In development mode, `tick()` also performs a second change detection cycle to ensure that no * further changes are detected. If additional changes are picked up during this second cycle, * bindings in the app have side-effects that cannot be resolved in a single change detection * pass. * In this case, Angular throws an error, since an Angular application can only have one change * detection pass during which all change detection must complete. * /
    tick() {
        if (this._runningTick) {
            throw new Error('ApplicationRef.tick is called recursively');
        }
        try {
            this._runningTick = true;
            for (let view of this._views) {
                view.detectChanges();
            }
            if (this._enforceNoNewChanges) {
                for (let view of this._views) { view.checkNoChanges(); }}}catch (e) {
            // Attention: Don't rethrow as it could cancel subscriptions to Observables!
            this._zone.runOutsideAngular(() = > this._exceptionHandler.handleError(e));
        }
        finally {
            this._runningTick = false; }}Copy the code

Call refreshView recursively:

“RefreshView” :

The debugger can see the host DOM element to which the template belongs, in this case the first div element in the UnitDetailsComponent cX-org-card tag:

Here the property and value of the setter to be executed are automatically generated:

Highlight is highlighted in the third line:



function ngOnChangesSetInput(instance, value, publicName, privateName) {
    const simpleChangesStore = getSimpleChangesStore(instance) ||
        setSimpleChangesStore(instance, { previous: EMPTY_OBJ, current: null });
    const current = simpleChangesStore.current || (simpleChangesStore.current = {});
    const previous = simpleChangesStore.previous;
    const declaredName = this.declaredInputs[publicName];
    const previousChange = previous[declaredName];
    current[declaredName] = new SimpleChange(previousChange && previousChange.currentValue, value, previous === EMPTY_OBJ);
    instance[privateName] = value;
}
Copy the code

Instance: FocusDirective

This __ngSimpleChanges__ should not be used by applications:



More of Jerry’s original articles can be found in “Wang Zixi” :