Javascript 自定义控件-数据绑定不起作用

Javascript 自定义控件-数据绑定不起作用,javascript,sapui5,Javascript,Sapui5,我目前正在尝试扩展sap.m.Input字段,以便能够设置标签放置的样式并扩展标签放置。 渲染工作正常,但数据绑定在过程中不知何故丢失了,我不确定这是为什么。这是我的控制: sap.ui.define([ 'sap/m/Input', ], function(Input) { 'use strict'; return Input.extend('one.sj.control.BhTextInput', { metadata: { properties: {

我目前正在尝试扩展
sap.m.Input
字段,以便能够设置标签放置的样式并扩展标签放置。 渲染工作正常,但数据绑定在过程中不知何故丢失了,我不确定这是为什么。这是我的控制:

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

  return Input.extend('one.sj.control.BhTextInput', {
    metadata: {
      properties: {
        label: {
          type: 'string',
        },
      },
      aggregations: {
          icon: {
            type: 'sap.ui.core.Icon',
            multiple: false,
            visibility: 'public',
          },
      },
    },

    renderer: function(oRM, oControl) {
      oRM.write('<div class="formControl">');

      oRM.write('<input placeholder="'+oControl.getPlaceholder()+'"');
      oRM.write('type="'+oControl.getType()+'"');
      oRM.write('value="'+oControl.getValue()+'"');
      oRM.writeClasses();
      oRM.writeControlData(oControl);
      oRM.write('/>');
      oRM.write('<label class="inputLabel" for="'+oControl.getId()+'"');
      oRM.write('>');
      oRM.renderControl(oControl.getIcon());
      oRM.write('<span class="inputLabelContent">');
      oRM.write(oControl.getLabel());
      oRM.write('</span>');
      oRM.write('</label>');

      oRM.write('</div>');
    },
  });
});
你能发现什么不对劲吗?谢谢


编辑:澄清一下我所说的“数据绑定丢失”是什么意思。当访问绑定到控制器内输入字段的值时,我只得到一个空字符串,如下所示:
getModel('creds').getProperty('/username')。这在替换上面所述的手动构造时确实有效。

我不确定这是否是导致问题的原因,但我相信oRM.write不会在呈现的HTML中添加空格。最好使用oRM.writeAttribute来编写属性。另外,应该使用oRM.addClass添加类。

我不确定这是否是导致问题的原因,但我相信oRM.write不会在呈现的HTML中添加空格。最好使用oRM.writeAttribute来编写属性。还应使用oRM.addClass添加类。

确定。要使其正常工作,需要进行几项更改

注意1:InputBase API(sap.m.Input的父级)需要
标记具有包含
“内部”
的id才能正确获取其值。这来自INputBase API:


/**
*返回相对于maxLength的DOM值
*设置参数时,切掉给定参数
*
*TODO:为两种不同的行为编写两个不同的函数
*/

InputBase.prototype._getInputValue = function(sValue) {
        sValue = (sValue === undefined) ? this.$("inner").val() || "" : sValue.toString();

        if (this.getMaxLength && this.getMaxLength() > 0) {
            sValue = sValue.substring(0, this.getMaxLength());
        }

        return sValue;
    };
InputBase.prototype.onChange = function(oEvent) {

    // check the control is editable or not
    if (!this.getEditable() || !this.getEnabled()) {
        return;
    }

    // get the dom value respect to max length
    var sValue = this._getInputValue();

    // compare with the old known value
    if (sValue !== this._lastValue) {

        // save the value on change
        this.setValue(sValue);

        if (oEvent) {
        //IE10+ fires Input event when Non-ASCII characters are used. As this is a real change
        // event shouldn't be ignored.
            this._bIgnoreNextInputEventNonASCII = false;
        }


        // get the value back maybe formatted
        sValue = this.getValue();

        // remember the last value on change
        this._lastValue = sValue;

        // fire change event
        this.fireChangeEvent(sValue);

        // inform change detection
        return true;
    } else {
        // same value as before --> ignore Dom update
        this._bCheckDomValue = false;
    }
};
因此,每次更改时,它都会读取DOM值,然后更新控件元数据

/**
*处理更改事件。
*
*@受保护
*@param{object}oEvent
*@在触发更改事件时返回{true | undefined}true
*/

InputBase.prototype._getInputValue = function(sValue) {
        sValue = (sValue === undefined) ? this.$("inner").val() || "" : sValue.toString();

        if (this.getMaxLength && this.getMaxLength() > 0) {
            sValue = sValue.substring(0, this.getMaxLength());
        }

        return sValue;
    };
InputBase.prototype.onChange = function(oEvent) {

    // check the control is editable or not
    if (!this.getEditable() || !this.getEnabled()) {
        return;
    }

    // get the dom value respect to max length
    var sValue = this._getInputValue();

    // compare with the old known value
    if (sValue !== this._lastValue) {

        // save the value on change
        this.setValue(sValue);

        if (oEvent) {
        //IE10+ fires Input event when Non-ASCII characters are used. As this is a real change
        // event shouldn't be ignored.
            this._bIgnoreNextInputEventNonASCII = false;
        }


        // get the value back maybe formatted
        sValue = this.getValue();

        // remember the last value on change
        this._lastValue = sValue;

        // fire change event
        this.fireChangeEvent(sValue);

        // inform change detection
        return true;
    } else {
        // same value as before --> ignore Dom update
        this._bCheckDomValue = false;
    }
};
所以,我更改了控件的渲染器方法,如下所示:

renderer: function(oRM, oControl) {
      oRM.write('<div class=formControl');
      oRM.writeClasses();
      oRM.writeControlData(oControl); // let div handle control metadata such as id.
      oRM.write(">")
      oRM.write('<input placeholder="'+oControl.getPlaceholder()+'"');
      oRM.write('id="'+oControl.getId()+'-inner"'); // set id with 'inner' 
//      oRM.write('type="'+oControl.getType()+'"'); dont know why type is throwing error s=, so had to comment it.
      oRM.write('value="'+oControl.getMyValue()+'"');
//      oRM.writeClasses();
//      oRM.writeControlData(oControl);
      oRM.write('/>');
      oRM.write('<label class="inputLabel" for="'+oControl.getId()+'"');
      oRM.write('>');
      oRM.renderControl(oControl.getIcon());
      oRM.write('<span class="inputLabelContent">');
      oRM.write(oControl.getLabel());
      oRM.write('</span>');
      oRM.write('</label>');

      oRM.write('</div>');
}
渲染器:函数(oRM、oControl){

oRM.write('Ok)。要使其正常工作,需要进行几项更改

注意1:InputBase API(sap.m.Input的父级)需要
标记具有包含
“内部”
的id才能正确获取其值。这来自InputBase API:


/**
*返回相对于maxLength的DOM值
*设置参数时,切掉给定参数
*
*TODO:为两种不同的行为编写两个不同的函数
*/

InputBase.prototype._getInputValue = function(sValue) {
        sValue = (sValue === undefined) ? this.$("inner").val() || "" : sValue.toString();

        if (this.getMaxLength && this.getMaxLength() > 0) {
            sValue = sValue.substring(0, this.getMaxLength());
        }

        return sValue;
    };
InputBase.prototype.onChange = function(oEvent) {

    // check the control is editable or not
    if (!this.getEditable() || !this.getEnabled()) {
        return;
    }

    // get the dom value respect to max length
    var sValue = this._getInputValue();

    // compare with the old known value
    if (sValue !== this._lastValue) {

        // save the value on change
        this.setValue(sValue);

        if (oEvent) {
        //IE10+ fires Input event when Non-ASCII characters are used. As this is a real change
        // event shouldn't be ignored.
            this._bIgnoreNextInputEventNonASCII = false;
        }


        // get the value back maybe formatted
        sValue = this.getValue();

        // remember the last value on change
        this._lastValue = sValue;

        // fire change event
        this.fireChangeEvent(sValue);

        // inform change detection
        return true;
    } else {
        // same value as before --> ignore Dom update
        this._bCheckDomValue = false;
    }
};
因此,每次更改时,它都会读取DOM值,然后更新控件元数据

/**
*处理更改事件。
*
*@受保护
*@param{object}oEvent
*@在触发更改事件时返回{true | undefined}true
*/

InputBase.prototype._getInputValue = function(sValue) {
        sValue = (sValue === undefined) ? this.$("inner").val() || "" : sValue.toString();

        if (this.getMaxLength && this.getMaxLength() > 0) {
            sValue = sValue.substring(0, this.getMaxLength());
        }

        return sValue;
    };
InputBase.prototype.onChange = function(oEvent) {

    // check the control is editable or not
    if (!this.getEditable() || !this.getEnabled()) {
        return;
    }

    // get the dom value respect to max length
    var sValue = this._getInputValue();

    // compare with the old known value
    if (sValue !== this._lastValue) {

        // save the value on change
        this.setValue(sValue);

        if (oEvent) {
        //IE10+ fires Input event when Non-ASCII characters are used. As this is a real change
        // event shouldn't be ignored.
            this._bIgnoreNextInputEventNonASCII = false;
        }


        // get the value back maybe formatted
        sValue = this.getValue();

        // remember the last value on change
        this._lastValue = sValue;

        // fire change event
        this.fireChangeEvent(sValue);

        // inform change detection
        return true;
    } else {
        // same value as before --> ignore Dom update
        this._bCheckDomValue = false;
    }
};
所以,我更改了控件的渲染器方法,如下所示:

renderer: function(oRM, oControl) {
      oRM.write('<div class=formControl');
      oRM.writeClasses();
      oRM.writeControlData(oControl); // let div handle control metadata such as id.
      oRM.write(">")
      oRM.write('<input placeholder="'+oControl.getPlaceholder()+'"');
      oRM.write('id="'+oControl.getId()+'-inner"'); // set id with 'inner' 
//      oRM.write('type="'+oControl.getType()+'"'); dont know why type is throwing error s=, so had to comment it.
      oRM.write('value="'+oControl.getMyValue()+'"');
//      oRM.writeClasses();
//      oRM.writeControlData(oControl);
      oRM.write('/>');
      oRM.write('<label class="inputLabel" for="'+oControl.getId()+'"');
      oRM.write('>');
      oRM.renderControl(oControl.getIcon());
      oRM.write('<span class="inputLabelContent">');
      oRM.write(oControl.getLabel());
      oRM.write('</span>');
      oRM.write('</label>');

      oRM.write('</div>');
}
渲染器:函数(oRM、oControl){

oRM.write('谢谢。我不知道writeAttribute。遗憾的是,这并没有改变任何事情。我目前的解决方案只是使用InputRenderer。我相信,由于输入实际上没有呈现,因此也不会调用输入的onAfterRendering,这可能是由于发生了一些绑定。也许您可以共享生成的HTML标记?谢谢。我不知道writeAttribute。遗憾的是,这并没有改变任何事情。我目前的解决方案只是使用InputRenderer。我相信,由于输入没有实际呈现,因此也不会调用输入的onAfterRendering,这可能是因为发生了一些绑定。也许您可以共享生成的HTML标记?