onAfterRendering hook สำหรับ smartform ใน UI5

ในแอปของฉัน ฉันมีมุมมอง XML ที่ประกอบด้วย smartform ฉันจำเป็นต้องเข้าถึงองค์ประกอบอินพุต (ผ่าน sap.ui.getCore().byId()) ที่พร้อมใช้งานหลังจากแยกวิเคราะห์และเรนเดอร์สมาร์ทฟอร์มแล้ว

onAfterRendering ในคอนโทรลเลอร์สำหรับมุมมองของฉันจะทริกเกอร์ทันทีที่มุมมองถูกเรนเดอร์ (ฉันได้รับองค์ประกอบที่ไม่ใช่สมาร์ทฟอร์มทั้งหมด เช่น ชื่อ ฯลฯ) แต่ก่อนที่สมาร์ทฟอร์มจะถูกแยกวิเคราะห์และเรนเดอร์ การทดสอบเบื้องต้นผ่าน alert ก็พิสูจน์สิ่งนี้ด้วยสายตาเช่นกัน

มีเหตุการณ์ใดบ้างที่เกิดขึ้นเมื่อสมาร์ทฟอร์มแสดงผลแล้ว ซึ่งฉันสามารถเชื่อมต่อเพื่อเข้าถึงองค์ประกอบอินพุตของฉันได้

คู่มือนักพัฒนา คำแนะนำแบบทีละขั้นตอนกำลังขยาย Smartform และจึงมี init แต่ในกรณีของฉัน ฉันกำลังขยาย basecontroller และ init ของฉันมีไว้สำหรับการดูหน้าเว็บ

ขอบคุณสำหรับคำแนะนำใด ๆ

มุมมองของฉัน:

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

My 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....
     }
});

});


person arunmenon    schedule 20.06.2016    source แหล่งที่มา


คำตอบ (2)


คุณสามารถค้นหาเมื่อมีการเพิ่ม SmartForm ใน DOM ด้วยเหตุการณ์ DOMNodeInserted ของ jQuery สำหรับสิ่งนี้ คุณสามารถใช้ id เพื่อระบุ SmartForm ที่ถูกเพิ่มใน DOM

องค์ประกอบ UI5 ทุกองค์ประกอบจะมีคำนำหน้าหลังจากเพิ่มลงใน DOM แล้ว

สำหรับเช่น __xmlview0--แบบฟอร์ม

ดังนั้นเพื่อให้แน่ใจว่าเพิ่มแบบฟอร์มที่ต้องการแล้ว คุณสามารถ split id ขององค์ประกอบที่เพิ่มเข้าไปได้ จากนั้นเปรียบเทียบกับ id ที่คุณให้ไว้

แม้ว่าจะไม่ใช่วิธีแก้ปัญหาที่ดีที่สุด แต่คุณสามารถลองได้

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");
            }
        }
    })
}
person Ashish Patil    schedule 20.06.2016
comment
ขอบคุณสำหรับคำตอบ. นี่เป็นวิธีแก้ปัญหาที่น่าสนใจ และ 'เกือบ' จะเป็นคำตอบสำหรับคำถามหลัก ฉันเดาว่ามันจะเป็นคำตอบที่สมบูรณ์แบบหากไม่มีเหตุการณ์ inbuilt ใด ๆ ที่ปล่อยออกมาจาก UI5 แน่นอน เนื่องจากมีการเชื่อมโยงอย่างแน่นหนากับ jQuery สิ่งนี้จึงได้ผลอย่างแน่นอน การอ่าน DOM เป็นทางเลือกเสมอไป แต่ฉันไม่แน่ใจว่ามี hooks ที่มีอยู่ที่ฉันอาจพลาดไปหรือไม่ - person arunmenon; 20.06.2016
comment
ตัวเลือกอื่นที่ฉันกำลังพิจารณาคือมี มุมมองแบบซ้อน โดยที่ฟอร์มอัจฉริยะของฉันมี มุมมองและตัวควบคุมของตัวเอง (และด้วยเหตุนี้ init และ onAfterRendering) ฉันไม่ได้ลองสิ่งนี้ แต่ตามทฤษฎีแล้วมันดูเป็นตัวเลือกที่ใช้การได้ - person arunmenon; 20.06.2016
comment
ฉันลองใช้เส้นทางที่ซ้อนกันแล้ว และก็มีปัญหาเดียวกันใน onAfterRendering ภายในมุมมองที่ซ้อนกันเช่นกัน ฉันต้องแนบกิจกรรมเพิ่มเติม (โฟกัส/เบลอ ฯลฯ) กับบางฟิลด์ ดังนั้นฉันจึงไปทั้งเส้นทางที่ซ้อนกันและเพิ่มเหตุการณ์ DOMNodeInserted จากโซลูชันของคุณ ด้วยเหตุผลบางอย่าง attachBrowserEvent ไม่ทำงาน ดังนั้นฉันจึงใช้ jQuery เพื่อแนบกิจกรรม ฉันกำลังตั้งค่าสถานะโซลูชันของคุณตามคำตอบเนื่องจากตอนนี้ฉันค่อนข้างแน่ใจว่าไม่มี hooks ที่ตรงไปตรงมา - person arunmenon; 20.06.2016
comment
ขอบคุณอรุณ ดีใจที่ช่วยได้! :) - person Ashish Patil; 20.06.2016

วิธีแก้ปัญหาสุดท้ายของฉัน (สำหรับตอนนี้และใช้คำตอบที่ยอมรับโดย @Dopedev):

(ในตัวควบคุมสำหรับมุมมองแบบซ้อนที่มีสมาร์ทฟอร์ม)

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");
            }
        }
    });
}
person arunmenon    schedule 20.06.2016