2017-04-19 2 views
1

J'essaie actuellement d'étendre un champ sap.m.Input pour pouvoir mettre en forme et étendre le placement d'étiquettes. Le rendu fonctionne correctement, mais la liaison de données est perdue dans le processus et je ne sais pas pourquoi. Ceci est mon contrôle:Contrôle personnalisé - la liaison de données ne fonctionne pas

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

Comme vous pouvez le voir, c'est assez simple. Voici comment je l'utilise:

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

Je confirme ce n'est pas un problème de mon modèle, car il fonctionne très bien quand je remplace la construction <input/> manuel dans la méthode renderer ci-dessus:

sap.m.InputRenderer.render(oRM, oControl); 

Pouvez-vous repérer quelque chose de mal? Merci!

EDIT: Pour clarifier un peu ce que je veux dire par "perte de liaison de données". Je reçois seulement une chaîne vide quand j'accède à la valeur liée au champ d'entrée dans mon contrôleur comme ceci: getModel('creds').getProperty('/username');. Cela fonctionne lorsque vous remplacez la construction manuelle comme indiqué ci-dessus.

Répondre

0

Je ne suis pas sûr si c'est ce qui cause votre problème mais je crois que oRM.write n'ajoute pas d'espaces à votre HTML rendu. Il est préférable d'utiliser oRM.writeAttribute pour écrire des attributs. La classe doit également être ajoutée en utilisant oRM.addClass.

+0

Merci. Je ne savais pas à propos de writeAttribute. Malheureusement, cela ne change rien. Ma solution actuelle consiste simplement à utiliser InputRenderer. Je crois que parce que l'entrée n'est pas réellement rendu que l'onAfterRendering de l'entrée n'est pas appelée ce qui pourrait être une partie de la liaison se produit. – puelo

+0

Peut-être que vous pourriez partager vos tags HTML générés? – amiramw

0

Ok. Il y a quelques changements nécessaires pour que cela fonctionne.

Remarque 1: L'API InputBase (parent de sap.m.Input) a besoin de votre balise <input> pour avoir un ID contenant "inner" pour récupérer sa valeur correctement. Ceci est de l'API INputBase:

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

Ainsi, à chaque changement, il lit la valeur DOM et met à jour les métadonnées de contrôle.

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

J'ai donc changé votre méthode de contrôle du moteur de rendu comme ceci:

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

Laissez-moi savoir si cela fonctionne pour vous. :)