Angular应用从Component到Html的数据绑定是如何实现的 -数据流的讨论

    科技2024-04-18  9

    index.html里有个base标签页,href属性为/:

    getBaseElementHref:

    getBaseHref:

    relativePath里有个document.createElement(‘a’)动态创建的场景:

    Component html:

    <input [value]= "userInput"/>

    Component的userInput属性:

    运行时,Component属性userInput的值是如何流到HTML页面上去的?

    /** * 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. * @return {?} */ 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((/** * @return {?} */ () => this._exceptionHandler.handleError(e))); } finally { this._runningTick = false; } }

    function tickRootContext(rootContext) { for (let i = 0; i < rootContext.components.length; i++) { /** @type {?} */ const rootComponent = rootContext.components[i]; /** @type {?} */ const lView = (/** @type {?} */ (readPatchedLView(rootComponent))); /** @type {?} */ const tView = lView[TVIEW]; renderComponentOrTemplate(tView, lView, tView.template, rootComponent); } }

    在core.js的rootContext属性里,展开Components, 能看到所有AppComponent的属性和值:

    渲染UI:

    下面这是一个非常重要的从Component属性将值移动到UI上的方法:

    /** * @fileoverview added by tsickle * Generated from: packages/core/src/render3/instructions/property.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /** * Update a property on a selected element. * * Operates on the element selected by index via the {\@link select} instruction. * * If the property name also exists as an input property on one of the element's directives, * the component property will be set instead of the element property. This check must * be conducted at runtime so child components that add new `\@Inputs` don't have to be re-compiled * * \@codeGenApi * @template T * @param {?} propName Name of property. Because it is going to DOM, this is not subject to * renaming as part of minification. * @param {?} value New value to write. * @param {?=} sanitizer An optional function used to sanitize the value. * @return {?} This function returns itself so that it may be chained * (e.g. `property('name', ctx.name)('title', ctx.title)`) * */ function ɵɵproperty(propName, value, sanitizer) { /** @type {?} */ const lView = getLView(); /** @type {?} */ const bindingIndex = nextBindingIndex(); if (bindingUpdated(lView, bindingIndex, value)) { /** @type {?} */ const tView = getTView(); /** @type {?} */ const tNode = getSelectedTNode(); elementPropertyInternal(tView, tNode, lView, propName, value, lView[RENDERER], sanitizer, false); ngDevMode && storePropertyBindingMetadata(tView.data, tNode, propName, bindingIndex); } return ɵɵproperty; }

    renderer.setProperty:

    在这里给input的value属性赋的值:

    要获取更多Jerry的原创文章,请关注公众号"汪子熙":

    汪子熙 认证博客专家 前端框架 Node.js SAP JerryWang,2007年从电子科技大学计算机专业硕士毕业后加入SAP成都研究院工作至今。Jerry是SAP社区导师,SAP中国技术大使。2020年5月下旬,Jerry做了脑部肿瘤的开颅切除手术,对编程和人生又有了新的感悟。
    Processed: 0.024, SQL: 12