2017-04-19 64 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>'); 
} 

讓我知道這對你的作品。 :)