【问题标题】:How is data binding implemented in SAPUI5?SAPUI5中如何实现数据绑定?
【发布时间】:2023-03-11 22:07:01
【问题描述】:

在这个很棒的问题中:How to Implement DOM Data Binding in JavaScript 许多数据绑定实现细节都得到了很好的解释。

还有很多探索博客关于Angular中的脏检查,Vue.js中使用的Object.defineProperty和虚拟DOM等等……

但是在UI5 docs中,只有如何使用数据绑定。没有关于如何实现数据绑定的详细信息。

我已阅读有关 sap.ui.base.ManagedObjectsource code of it 的文档 .在constructor of sap.ui.base.ManagedObject 中,它说这些对象与数据绑定有关,但我不知道如何。有时我会将它们注销以调试我的数据绑定,但仍然没有大局:

        // data binding
        this.oModels = {};
        this.aPropagationListeners = [];
        this.oBindingContexts = {};
        this.mElementBindingContexts = {};
        this.mBindingInfos = {};
        this.mObjectBindingInfos = {};

也输在ManagedObject.prototype.bindObject

我真的希望了解当数据模型发生变化时,Dom 是如何更新的,反之亦然。

【问题讨论】:

  • 一点信息:Handlebars.js 框架被纳入 SAP UI5 用于数据绑定。
  • 如果只是为了调试,也许UI5 chrome扩展可以帮上忙。它会将页面上的元素显示为 UI5 元素而不是 HTML 元素,并且会显示这些元素上的绑定。在这里找到它:chrome.google.com/webstore/detail/ui5-inspector/…
  • @Jorg,是的,我知道,UI5 diagnostics,但我想知道的是实现细节。
  • 谢谢@santhosh,我在sap.ui.thirdparty找到了,我会深入研究一下。
  • 可能搜索 Handlebars.compile。

标签: javascript data-binding sapui5


【解决方案1】:

有的cmets说UI5使用Handlebars进行数据绑定,搜索后发现Handlebars只支持one-time data binding。我比较好奇的是UI5中双向数据绑定是如何实现的(很抱歉一开始没有说清楚)。

在Handlebars中,一旦你编译了你的模板,视图/DOM就与数据模型无关了。

但是双向数据绑定将数据连接到其本地 DOM 中元素的属性或属性。这意味着:

当模型中的属性更新时,UI 也会更新。当 UI 元素更新时,更改会传播回模型。 https://stackoverflow.com/a/13504965/5238583

How to Implement DOM Data Binding in JavaScript 的问题中,提到了很多技巧。 UI5 使用这两个(到目前为止我发现的):add change event listenermutators(setter)

我使用了这个官方示例,例如:Data Binding - Step 13 - Element Binding

数据绑定在什么时候改变 oProductDetailPanel.bindElement({ path: sPath, model: "products" }); 被调用。

oBinding.setContext() in ManagedObject.prototype.updateBindingContextManagedObject.prototype.updateProperty 中设置断点。您可以在调用堆栈中看到它。

TL;DR:核心步骤是 3、6、8

主要步骤是:

  1. Element.prototype.bindElement 等于 ManagedObject.prototype.bindObject

  2. oBinding.initialize() 表示ClientContextBinding.prototype.initializeManagedObject.prototype._bindObject 中被调用

  3. Binding.prototype._fireChangecreateBindingContext 回调中被调用。哪个火change事件:this.fireEvent("change", mArguments)

  4. 还有!更改事件处理程序在ManagedObject.prototype._bindObject 中定义:

    var fChangeHandler = function(oEvent) {
         that.setElementBindingContext(oBinding.getBoundContext(), sModelName);
    };
    oBinding.attachChange(fChangeHandler);
    oBindingInfo.modelChangeHandler = fChangeHandler;
    
  5. setElementBindingContext() 最终调用ManagedObject.prototype.updateBindingContext

  6. updateBindingContext中,调用栈是oBinding.setContext(oContext) -> JSONPropertyBinding.prototype.checkUpdate(因为这里的示例使用JSON模型) -> this._fireChange({reason: ChangeReason.Change})

  7. 对于第二个change事件,handler在ManagedObject.prototype._bindProperty中(ManagedObject的bind函数中有很多fModelChangeHandler,对于我们的bindElement示例,我们只需要这一个)

  8. fModelChangeHandler 中,ManagedObject.prototype.updateProperty 被调用。使用我们的 setter(mutator) 的地方:

每当属性绑定发生变化时。此方法从属性绑定中获取外部格式并将其应用于设置器。

this[oPropertyInfo._sMutator](oValue);。对于我们的示例oPropertyInfo._sMutatorsetValue。执行此操作,Input <Input value="{products>ProductID}"/> 中的值将被更改。

此处原记录:https://github.com/TinaC/Blog/blob/master/SAPUI5/Data_Binding.md

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-10-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多