自定义控件 - 数据绑定无效

时间:2017-04-19 15:54:08

标签: javascript sapui5

我目前正在尝试扩展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>');
    },
  });
});

你可以看到它很简单。 这就是我使用它的方式:

<sj:BhTextInput
    id="username" class="input textInput"
    placeholder="{i18n>HINT_USERNAME}" value="{creds>/username}"
    type="Text">
  <sj:icon>
    <core:Icon src="sap-icon://email" class="inputIcon" />
  </sj:icon>
</sj:BhTextInput>

我确认这不是我的模型的问题,因为当我用上面的<input/>方法替换手动renderer构造时它工作正常:

sap.m.InputRenderer.render(oRM, oControl);
你能发现什么问题吗?谢谢!

编辑:澄清“数据绑定迷失”的含义。在访问绑定到控制器内部的Input字段的值时,我只获取一个空字符串,如下所示:getModel('creds').getProperty('/username');。当如上所述更换手动结构时,这确实有效。

2 个答案:

答案 0 :(得分:0)

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

答案 1 :(得分:0)

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

注意1:InputBase API(sap.m.Input的父级)需要您的<input>标记包含一个包含"inner"的ID才能正确获取其值。这来自INputBase API:

/** * Returns the DOM value respect to maxLength * When parameter is set chops the given parameter * * TODO: write two different functions for two different behaviour */

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;
    };

因此,在每次更改时,它都会读取DOM值,然后更新控件元数据。

/** * Handles the change event. * * @protected * @param {object} oEvent * @returns {true|undefined} true when change event is fired */

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>');
}

如果这对您有用,请告诉我。 :)