Component HTML:
<input type="text" maxlength="40" nz-input placeholder="Input Book Name to search" [(ngModel)] ="bookName" (keyup) ="search(bookName)"
/>
Copy the code
The bookName is a Component property:
Runtime render to template containing [(ngModel)] :
Create a directive instance:
Create ngModel instance:
If I type an A in the UI, the Component’s bookName value will also be a because of bidirectional binding.
This function executes checkhooks whenever the refreshView redraw interface is triggered by a UI change:
/**
* Executing hooks requires complex logic as we need to deal with 2 constraints.
*
* 1. Init hooks (ngOnInit, ngAfterContentInit, ngAfterViewInit) must all be executed once and only
* once, across many change detection cycles. This must be true even if some hooks throw, or if
* some recursively trigger a change detection cycle.
* To solve that, it is required to track the state of the execution of these init hooks.
* This is done by storing and maintaining flags in the view: the {@link InitPhaseState},
* and the index within that phase. They can be seen as a cursor in the following structure:
* [[onInit1, onInit2], [afterContentInit1], [afterViewInit1, afterViewInit2, afterViewInit3]]
* They are are stored as flags in LView[FLAGS].
*
* 2. Pre-order hooks can be executed in batches, because of the select instruction.
* To be able to pause and resume their execution, we also need some state about the hook's array
* that is being processed:
* - the index of the next hook to be executed
* - the number of init hooks already found in the processed part of the array
* They are are stored as flags in LView[PREORDER_HOOK_FLAGS].
*/
/**
* Executes pre-order check hooks ( OnChanges, DoChanges) given a view where all the init hooks were
* executed once. This is a light version of executeInitAndCheckPreOrderHooks where we can skip read
* / write of the init-hooks related flags.
* @param {? } lView The LView where hooks are defined
* @param {? } hooks Hooks to be run
* @param {? =} nodeIndex 3 cases depending on the value:
* - undefined: all hooks from the array should be executed (post-order case)
* - null: execute hooks only from the saved index until the end of the array (pre-order case, when
* flushing the remaining hooks)
* - number: execute hooks only from the saved index until that node index exclusive (pre-order
* case, when executing select(number))
* @return {? }* /
function executeCheckHooks(lView, hooks, nodeIndex) {
callHooks(lView, hooks, 3 /* InitPhaseCompleted */, nodeIndex);
}
Copy the code
Function wrapOnChangesHook_inPreviousChangesStorage:
functionɵ ɵNgOnChangesFeature(definition) {
if (definition.type.prototype.ngOnChanges) {
definition.setInput = ngOnChangesSetInput;
((/ * *@type {? } * /(definition))).onChanges = wrapOnChanges(); }}// This option ensures that the ngOnChanges lifecycle hook will be inherited
// from superclasses (in InheritDefinitionFeature).
/ * *@nocollapse * /
// tslint:disable-next-line:no-toplevel-property-access
((/ * *@type {? } * /(ɵ ɵ NgOnChangesFeature))). NgInherit =true;
/ * * *@return {? }* /
function wrapOnChanges() {
return (/ * * *@this {? }
* @return {? }* /
function wrapOnChangesHook_inPreviousChangesStorage() {
/ * *@type {? } * /
const simpleChangesStore = getSimpleChangesStore(this);
/ * *@type {? } * /
const current = simpleChangesStore && simpleChangesStore.current;
if (current) {
/ * *@type {? } * /
const previous = (/ * *@type {? } * / (simpleChangesStore)).previous;
if (previous === EMPTY_OBJ) {
(/ * *@type {? } * / (simpleChangesStore)).previous = current;
}
else {
// New changes are copied to the previous store, so that we don't lose history for inputs
// which were not changed this time
for (let key incurrent) { previous[key] = current[key]; }} (/ * *@type {? } * / (simpleChangesStore)).current = null;
this.ngOnChanges(current); }}); }Copy the code
/**
* Wraps an event listener with a function that marks ancestors dirty and prevents default behavior,
* if applicable.
*
* @param {? } tNode The TNode associated with this listener
* @param {? } lView The LView that contains this listener
* @param {? } listenerFn The listener function to call
* @param {? } wrapWithPreventDefault Whether or not to prevent default behavior
* (the procedural renderer does this already, so in those cases, we should skip)
* @return {? }* /
function wrapListener(tNode, lView, listenerFn, wrapWithPreventDefault) {
// Note: we are performing most of the work in the listener function itself
// to optimize listener registration.
return (/ * * *@param {? } e
* @return {? }* /
function wrapListenerIn_markDirtyAndPreventDefault(e) {
// Ivy uses `Function` as a special token that allows us to unwrap the function
// so that it can be invoked programmatically by `DebugNode.triggerEventHandler`.
if (e === Function) {
return listenerFn;
}
// In order to be backwards compatible with View Engine, events on component host nodes
// must also mark the component view itself dirty (i.e. the view that it owns).
/ * *@type {? } * /
const startView = tNode.flags & 2 /* isComponentHost */ ?
getComponentLViewByIndex(tNode.index, lView) :
lView;
// See interfaces/view.ts for more on LViewFlags.ManualOnPush
if ((lView[FLAGS] & 32 /* ManualOnPush */) = = =0) {
markViewDirty(startView);
}
/ * *@type {? } * /
let result = executeListenerWithErrorHandling(lView, listenerFn, e);
// A just-invoked listener function might have coalesced listeners so we need to check for
// their presence and invoke as needed.
/ * *@type {? } * /
let nextListenerFn = ((/ * *@type {? } * / (wrapListenerIn_markDirtyAndPreventDefault))).__ngNextListenerFn__;
while (nextListenerFn) {
// We should prevent default if any of the listeners explicitly return false
result = executeListenerWithErrorHandling(lView, nextListenerFn, e) && result;
nextListenerFn = ((/ * *@type {? } * / (nextListenerFn))).__ngNextListenerFn__;
}
if (wrapWithPreventDefault && result === false) {
e.preventDefault();
// Necessary for legacy browsers that don't support preventDefault (e.g. IE)
e.returnValue = false;
}
return result;
});
}
Copy the code
Go to forms.js _handleInput(value):
For more of Jerry’s original articles, please follow the public account “Wang Zixi “: