2016-06-20 3 views
0

In meiner App habe ich eine XML-Ansicht, die aus einem smartform besteht. Ich muss auf ein Eingabeelement zugreifen (über sap.ui.getCore().byId()), das verfügbar wird, nachdem das Smartformular analysiert und gerendert wurde.onAfterRendering Hook für Smartform in UI5

Die onAfterRendering im Controller für meine Ansicht löst aus, sobald die Ansicht gerendert wird (ich bekomme alle meine nicht-Smartform-Elemente wie Titel usw.), aber bevor die Smartform geparst und gerendert wird. Ein rudimentärer Test über eine alert zeigte dies auch optisch.

Gibt es ein Ereignis, das ausgelöst wird, nachdem die Smartform gerendert hat, die ich einhaken kann, um auf mein Eingabeelement zuzugreifen?

Der Entwickler Guide walkthrough erweitert die Smartform und hat daher seine init Methode, aber in meinem Fall bin ich den Basiscontroller erweitern und meine Init ist für die Seitenansicht.

Danke für alle Hinweise.

Meine Ansicht:

<mvc:View 
controllerName="myns.controller.Add" 
xmlns:mvc="sap.ui.core.mvc" 
xmlns:semantic="sap.m.semantic" 
xmlns:smartfield="sap.ui.comp.smartfield" 
xmlns:smartform="sap.ui.comp.smartform" 
xmlns="sap.m"> 
<semantic:FullscreenPage 
    id="page" 
    title="{i18n>addPageTitle}" 
    showNavButton="true" 
    navButtonPress="onNavBack"> 
    <semantic:content> 
     <smartform:SmartForm 
      id="form" 
      editable="true" 
      title="{i18n>formTitle}" 
      class="sapUiResponsiveMargin" > 
      <smartform:Group 
       id="formGroup" 
       label="{i18n>formGroupLabel}"> 
       <smartform:GroupElement> 
        <smartfield:SmartField 
         id="nameField" 
         value="{Name}" /> 
       </smartform:GroupElement> 
      </smartform:Group> 
     </smartform:SmartForm> 
    </semantic:content> 
    <semantic:saveAction> 
     <semantic:SaveAction id="save" press="onSave"/> 
    </semantic:saveAction> 
    <semantic:cancelAction> 
     <semantic:CancelAction id="cancel" press="onCancel"/> 
    </semantic:cancelAction> 
</semantic:FullscreenPage> 

Mein Controller:

sap.ui.define([ 
"myns/controller/BaseController", 
"sap/ui/core/routing/History", 
"sap/m/MessageToast" 
],function(BaseController, History, MessageToast){ 
"use strict"; 
return BaseController.extend("myns.controller.Add",{ 
    onInit: function(){ 
     this.getRouter().getRoute("add").attachPatternMatched(this._onRouteMatched, this); 
    }, 
    onAfterRendering: function(){ 
     //I tried my sap.ui.getCore().byId() here but does not work 
     //An alert shows me this triggers before the smartform is rendered but 
     //after all the other non-smartform elements have rendered 
    }, 
    _onRouteMatched: function(){ 
     // register for metadata loaded events 
     var oModel = this.getModel(); 
     oModel.metadataLoaded().then(this._onMetadataLoaded.bind(this)); 
    }, 
    _onMetadataLoaded:function(){ 
     //code here.... 
    }, 
    onNavBack: function(){ 
     //code here.... 
    } 
}); 

});

Antwort

1

Sie können suchen, wenn SmartForm dem DOM mit DOMNodeInserted Ereignis von jQuery hinzugefügt wird. Für dieses können Sie es id verwenden, um das SmartForm zu identifizieren, das DOM hinzugefügt worden ist.

Jedes Element UI5 erhält ein Präfix, nachdem es dem DOM hinzugefügt wurde.

für z.B. __xmlview0 - Formular.

Um sicherzustellen, dass das erforderliche Formular hinzugefügt wird, können Sie die ID des hinzugefügten Elements split, dann vergleichen Sie es mit ID, die Sie angegeben haben.

Obwohl es nicht optimale Lösung ist, aber Sie können es versuchen.

onAfterRendering: function() { 
    $(document).bind('DOMNodeInserted', function(event) { 
     var aId = $(event.target).attr("id").split("--"); 
     var id = aId[aId.length - 1]; 
     if (id) { 
      if (id == "form") { 
       // smart form fields are accessible here 
       $(document).unbind("DOMNodeInserted"); 
      } 
     } 
    }) 
} 
+0

Vielen Dank für die Antworten. Dies ist eine interessante Lösung und "fast" die Antwort auf die primäre Frage. Ich denke, es wäre die perfekte Antwort, wenn es von der UI5 sicher kein eingebautes Ereignis gibt. Da es enge Kopplung mit jQuery gibt, wird dies definitiv funktionieren. Das DOM zu lesen war immer eine Option, aber ich war mir nicht sicher, ob es existierende Hooks gab, die ich verpasste. – arunmenon

+0

Eine andere Option, die ich in Betracht ziehe, ist [verschachtelte Ansichten] (https://openui5.hana.ondemand.com/docs/guide/df8c9c3d79b54c928855162bafcd88ee.html) mit meiner Smartform, die eine eigene Ansicht und einen eigenen Controller (und somit ein "init" hat) und 'onAfterRendering'). Ich habe das nicht versucht, aber theoretisch scheint es eine brauchbare Option zu sein. – arunmenon

+0

Ich habe versucht, die verschachtelte Route, und die hatte die gleichen Probleme in OnAfterRendering in der verschachtelten Ansicht. Ich musste zusätzlich Ereignisse (Fokus/Unschärfe usw.) an einige der Felder anhängen, also ging ich sowohl die verschachtelte Route als auch das 'DOMNodeInserted'-Ereignis aus Ihrer Lösung. Aus irgendeinem Grund funktionierte das 'attachBrowserEvent' nicht, also habe ich jQuery verwendet, um die Ereignisse anzuhängen. Ich werde Ihre Lösung als beantwortet markieren, da ich mir jetzt ziemlich sicher bin, dass es keine einfachen Haken gibt. – arunmenon

0

Meine letzte Lösung (für jetzt und verwendet die akzeptierte Antwort zur Verfügung gestellt von @Dopedev):

(in der Steuerung für die verschachtelte Ansicht, welche die Smart)

onAfterRendering: function() { 
    $(document).bind('DOMNodeInserted', function(event) { 
     var elem = $(event.target); 
     var aId = elem.attr("id").split("--"); 
     var id = aId[aId.length - 1]; 
     if (id) { 
      if (id == "nameField") { 
       elem.find("input").on({ 
        focus: function(oEvent) { 
         //code here; 
        }, 
        blur: function(oEvent) { 
         //code here; 
        } 
       }); 
       /* 
       elem.find("input").get(0).attachBrowserEvent("focus", function(evt) { 
        //code here 
       }).attachBrowserEvent("blur", function(ev) { 
        //code here 
       }); 
       */ 
       $(document).unbind("DOMNodeInserted"); 
      } 
     } 
    }); 
}