Обновление модели в UI5, двустороннее связывание данных становится односторонним при использовании форматера - PullRequest
3 голосов
/ 06 июня 2019

В моем UI5-приложении у меня есть таблица, в которой каждая строка содержит sap.m.Switch, который привязан к модели через formatter, поскольку данные поступают из БД как 1 / 0, а не true / false, и это, вероятно, нарушает стандартную двустороннюю привязку данных .

Чтобы обновить модель данных после редактирования значения этого переключателя, я реализовал следующее change -event:

onChangeSwitch: function onChangeSwitch(oEvent) {
    let context = oEvent.oSource.getBindingContext();
    let itemIndex = context.sPath.substr(1);
    let oModel = this.getView().byId("idTablePersons").getModel();
    oModel.oData[itemIndex].isPersonActive = (oEvent.mParameters.state) ? 1 : 0;
    oModel.refresh();
}

Это работает, но я не уверен, что это правильный способ реализовать такую ​​логику.
Существует ли стандартный способ обновления модели после изменения значения sap.m.Switch?

1 Ответ

3 голосов
/ 07 июня 2019

Я думаю, что вы подходите к этому неправильно. sap.m.Switch уже имеет атрибут для указания состояния, которое можно напрямую связать с моделью.

<Switch state="{IsPersonActive}" />

Предполагая, что вы привязали элементы в таблице к безымянной модели, для флага IsPersonActive на связанной строке будет установлено значение true или false в зависимости от состояния переключателя.

Это также означает, что переключатели будут в правильном состоянии, если определенные IsPersonActive флаги уже установлены в true или false в ваших наборах сущностей.


(…) данные поступают из БД как 1 / 0, а не true / false (…).
Существует ли стандартный способ обновления модели после изменения значения sap.m.Switch?

Исправлено двустороннее связывание данных с https://embed.plnkr.co/wwQXf8bTuiTP4RlP:

NumericBoolean.js (в папке модель / тип ):

sap.ui.define(['sap/ui/model/SimpleType'], function(SimpleType) {
    'use strict';

    return SimpleType.extend('demo.model.type.NumericBoolean', {

        constructor: function() {
            SimpleType.apply(this, arguments);
        },

        formatValue: function(iValue) {
            return !!iValue;
        },

        parseValue: function(bValue) {
            return bValue ? 1 : 0;
        },

        validateValue: function() {
            // this method must be declared, even without implementation
        },
    });
});

Важное примечание:
Обязательно хранить декларацию validateValue, даже если реализация не указана, иначе sap.m.Switch не будет работать правильно.

index.html (в корневой папке):

<!DOCTYPE HTML>
<html style="height: 100%;">

<head>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">

    <title>Demo</title>

    <script
        id="sap-ui-bootstrap"
        src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
        data-sap-ui-theme="sap_fiori_3"
        data-sap-ui-libs="sap.ui.core, sap.m"
        data-sap-ui-async="true"
        data-sap-ui-compatVersion="edge"
        data-sap-ui-resourceroots='{"demo": "./"}'
        data-sap-ui-xx-waitForTheme="true">
    </script>

    <script>
        sap.ui.getCore().attachInit(() => sap.ui.require([
            "sap/ui/core/mvc/XMLView",
            "sap/ui/model/json/JSONModel",
            "demo/model/type/NumericBoolean", // define and export it globally
        ], (XMLView, JSONModel) => XMLView.create({

            definition:
                `<mvc:View xmlns:mvc="sap.ui.core.mvc">
                    <VBox xmlns="sap.m" renderType="Bare" class="sapUiTinyMargin">
                        <ObjectStatus title="Model data" text="{/1or0}" />
                        <Switch state="{
                            path: '/1or0',
                            type: 'demo.model.type.NumericBoolean'
                        }"
                        type="AcceptReject" />
                    </VBox>
                </mvc:View>`,

            models: new JSONModel({ "1or0": 1 }),

        }).then(view => view.placeAt("content"))));
    </script>
</head>

<body id="content" class="sapUiBody" style="height: 100%"></body>

</html>
...