2017-04-19 66 views
1

我目前正试图扩展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); 

你能发现任何错误吗?谢谢!

编辑:澄清一下我的意思是“数据绑定丢失”。当我访问像我这样的控制器内的输入字段的值时,我只会得到一个空字符串:getModel('creds').getProperty('/username');。这在替换上述手动结构时可以工作。

回答

0

我不确定这是什么原因导致您的问题,但我相信oRM.write不会为您的呈现HTML添加空格。使用oRM.writeAttribute写属性更好。还应该使用oRM.addClass添加类。

+0

谢谢。我不知道writeAttribute。可悲的是这并没有改变任何东西。我目前的解决方案只是使用InputRenderer。我相信因为Input并不是实际呈现的,所以输入的onAfterRendering也不会被调用,这可能是某些绑定发生。 – puelo

+0

也许你可以分享你生成的HTML标签? – amiramw

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

让我知道这对你的作品。 :)