如何在UI5中正确附加和分离事件处理程序

How to properly attach and detach event handler in UI5(如何在UI5中正确附加和分离事件处理程序)
本文介绍了如何在UI5中正确附加和分离事件处理程序的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我的自定义控件的数据绑定有问题。

我的控件继承自sap.m.Input,并使用特殊的值helper对其进行扩展。我的新控件的一个新属性是Value Help对话框的一个简单标题。这绑定到I18N模型。

当我现在以正常形式使用我的控件时,一切都可以正常工作。标题已正确绑定,并显示该模型中绑定的I18N属性的值。如果我将我的控件用作sap.ui.table控件列中的模板,它只显示Title属性的默认值。数据绑定似乎不起作用。但仍在处理继承的属性(如值)。

为简化起见,我控件现在只有Title属性,如果请求Value Help,它会在警告框中显示当前值。在表中,显示默认值。并且没有表格,它显示来自I18N模型的绑定值。

这里是简化的控件代码:

sap.ui.define([
  "sap/ui/core/Control",
  "sap/m/Input",
], function(Control, Input) {
  "use strict";

  return Input.extend("DvpClsSuggestInput", {
    "metadata": {
        "properties": {
          // Title of Value-Help Dialog
          "vhTitle": {
            type: "string",
            defaultValue: "Title"
          }
        }
      },
    
      init: function() {
        Input.prototype.init.apply(this, arguments);
        this.setShowValueHelp(true);
        this.attachValueHelpRequest(this.onValueHelpRequest.bind(this));
      },
    
      onValueHelpRequest: function(oEvent) {
        var lvTitle = this.getVhTitle();
        alert(lvTitle);
      },

    });
  });
});

sap.ui.table.Table中的用法(不起作用,显示Title属性的默认值):

<table:Column>
  <m:Label text="{i18gn>HausWaehrung}" />
  <table:template>
    <dvp:MyInput
      value="{ path: 'Inv>Hwaer', type: 'sap.ui.model.type.String' }"
      vhTitle="{i18n>Currency}" />
  </table:template>
</table:column>         

有效的用法:

<VBox>
  <dvp:MyInput
    value="{ path: 'Cls>/Currency', type: 'sap.ui.model.type.String' }"
    vhTitle="{i18n>Currency}" />
</VBox>
同样,针对value属性的绑定在两种情况下都有效。问题只存在于我自己的属性vhTitle。欢迎任何想法。

推荐答案

将事件处理程序附加到ManagedObject的事件时,请勿使用.bind。分离事件处理程序也是如此。UI5在这些情况下有自己的记录机制来传递侦听器对象。

示例%1

Attaching/detachingvalueHelpRequest-处理程序使用相应的API并将值传递到参数列表,如API参考中所述

myInput.attachValueHelpRequest(/*obj?,*/this.onValueHelpRequest, this); // No .bind!
myInput.detachValueHelpRequest(this.onValueHelpRequest, this); // Same references

示例2

将事件处理程序附加到控件实例化,如ManagedObject's API reference中所述(所有控件均为ManagedObjects):

new MyInput({
  // ...,
  valueHelpRequest: [/*obj?,*/this.onValueHelpRequest, this]
});

有效名称和值范围:

  • [.]
  • 对于事件,要么接受函数(事件处理程序),要么是长度为2的数组,其中第一个元素是函数,第二个元素是要调用方法的对象;或者是长度为3的数组,其中第一个元素是任意负载对象,第二个是函数,第三个是调用[.]方法的对象。

示例3(面向控件开发人员)

但是,在控件定义中,可以完全省略侦听器,因为如果没有传递侦听器对象,则事件提供程序本身(即您的控件实例)在默认情况下将成为侦听器。

this.attachValueHelpRequest(this.onValueHelpRequest); // the control instance will be used as the context in that event handler

API reference中也有说明:

如果未指定<;oListener>;,则在事件提供程序的上下文中调用处理程序函数。

在UI5中使用Function.prototype.bind的缺点

  1. 在函数上调用.bind时,创建了一个完整的函数!

    const myFn = function() {};
    myFn === myFn.bind(); // returns: false
    

    表示如果使用.bind传递处理程序,则该处理程序将变为永远不可分离,因为detachEvent等待与调用attachEvent时相同的函数引用和侦听器对象引用。

  2. 更糟糕的是,使用.bind创建的函数不允许您更改之前传递的thisArg(this),即使EventProvider tries to call之后使用不同的thisArg来更改函数。ECMAScript specification(请参阅注释2)中描述了此限制,也说明了问题中描述的问题的原因。ManagedObject克隆聚合绑定的template控件时,不能覆盖监听器!

这篇关于如何在UI5中正确附加和分离事件处理程序的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持编程学习网!

本站部分内容来源互联网,如果有图片或者内容侵犯您的权益请联系我们删除!

相关文档推荐

Update another component when Formik form changes(当Formik表单更改时更新另一个组件)
Formik validation isSubmitting / isValidating not getting set to true(Formik验证正在提交/isValiating未设置为True)
React Validation Max Range Using Formik(使用Formik的Reaction验证最大范围)
Validation using Yup to check string or number length(使用YUP检查字符串或数字长度的验证)
Updating initialValues prop on Formik Form does not update input value(更新Formik表单上的初始值属性不会更新输入值)
password validation with yup and formik(使用YUP和Formick进行密码验证)