Хук onAfterRendering для смарт-формы в UI5

В моем приложении у меня есть XML-представление, состоящее из смарт-формы. Мне нужно получить доступ к элементу ввода (через sap.ui.getCore().byId()), который становится доступным после анализа и отображения смарт-формы.

onAfterRendering в контроллере для моего представления срабатывает, как только представление отображается (я получаю все свои элементы, не относящиеся к смарт-формам, такие как заголовок и т. д.), но до того, как смарт-форма анализируется и отображается. Элементарный тест с помощью alert также наглядно подтвердил это.

Есть ли какое-либо событие, которое запускается после отображения смарт-формы, к которому я могу подключиться для доступа к моему элементу ввода?

Руководство разработчика пошаговое руководство расширяет смарт-форму и, таким образом, имеет свою 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 указать идентификатор добавленного элемента, а затем сравнить его с идентификатором, который вы указали.

Хоть это и не оптимальное решение, но попробовать можно.

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
Спасибо за ответ. Это интересное решение и «почти» ответ на основной вопрос. Я думаю, это был бы идеальный ответ, если бы UI5 точно не создавал встроенных событий. Поскольку существует тесная связь с jQuery, это определенно сработает. Чтение DOM всегда было вариантом, но я не был уверен, есть ли какие-то крючки, которые я мог пропустить. - person arunmenon; 20.06.2016
comment
Другой вариант, который я рассматриваю, — иметь вложенные представления с моей смарт-формой, имеющей свое собственное представление и контроллер (и, следовательно, init и onAfterRendering). Я не пробовал это, но теоретически это выглядит жизнеспособным вариантом. - person arunmenon; 20.06.2016
comment
Я попробовал вложенный маршрут, и у меня были те же проблемы в onAfterRendering во вложенном представлении. Мне пришлось дополнительно прикрепить события (фокус/размытие и т. д.) к некоторым полям, поэтому я пошел как по вложенному маршруту, так и добавил событие DOMNodeInserted из вашего решения. По какой-то причине attachBrowserEvent не работал, поэтому я использовал jQuery для присоединения событий. Я помечаю ваше решение как ответ, так как к настоящему времени я совершенно уверен, что нет простых крючков. - 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