首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >无法从sapUI5内核访问模型

无法从sapUI5内核访问模型
EN

Stack Overflow用户
提问于 2015-12-08 19:31:39
回答 4查看 15.3K关注 0票数 3

跟进相关问题这里

无论出于什么原因,当通过sap.ui.getCore().setModel()设置模型时,我无法访问xml视图中的模型。如果我将其设置在this.getView()上,则完全没有问题。

我的观点XML

代码语言:javascript
复制
<mvc:View controllerName="ca.toronto.rcsmls.webapp.controller.Login"
xmlns="sap.m" xmlns:mvc="sap.ui.core.mvc" xmlns:l="sap.ui.layout">

<Page title="{i18n>loginPageTitle}">
    <content>

        <Panel id="loginPanel" busyIndicatorDelay="0"
            headerText="{i18n>loginPanelTitle}" class="sapUiResponsiveMargin loginPanel"
            width="auto">
            <l:VerticalLayout width="100%">


                <Input type="Text" placeholder="{i18n>loginUidHolder}" value="{/mlsUser/uid}" />

                <Input type="Password" placeholder="{app>/Password}"
                    value="{/mlsUser/password}" />

                <Button text="{i18n>loginButtonText}" press="doLogin"
                    class="sapUiSmallMarginEnd customBold" width="100%" />


            </l:VerticalLayout>
        </Panel>

    </content>
</Page></mvc:View>

我的控制器JS包含了setModel()

代码语言:javascript
复制
 onInit : function() {
        sap.ui.getCore().setModel(new sap.ui.model.json.JSONModel("webapp/controller/app.json"), "app");
    }

同样,如果我将模型设置为this.getView().setModel()而不是getCore() XML和控制器可以很好地协同工作。我还将data-sap-ui-xx-bindingSyntax="complex"添加到我的index.html中,但这似乎没有什么区别。任何帮助都将不胜感激。

编辑以包含更多信息

我的Component.js

代码语言:javascript
复制
sap.ui.define([
   "sap/ui/core/UIComponent",
   "sap/ui/model/json/JSONModel",
], function (UIComponent, JSONModel) {
   "use strict";
   return UIComponent.extend("ca.toronto.rcsmls.webapp.Component", {
      metadata : {
          manifest: "json"
      },
      init : function () {
         // call the init function of the parent
         UIComponent.prototype.init.apply(this, arguments);
         // set data model
         var oData = {
            mlsUser : {
               uid : "",
               password : "",
            }
         };
         var oModel = new JSONModel(oData);
         this.setModel(oModel);

         // create the views based on the url/hash
         this.getRouter().initialize();
      }
   });
});

我的manifest.json

代码语言:javascript
复制
{
    "_version": "1.1.0",
    "sap.app": 
    {
        "_version": "1.1.0",
        "id": "ca.toronto.rcsmls",
        "type": "application",
        "i18n": "i18n/i18n.properties",
        "title": "{{appTitle}}",
        "description": "{{appDescription}}",
        "applicationVersion": 
        {
            "version": "1.0.0"
        },

        "ach": "CA-UI5-DOC"
    },

    "sap.ui": 
    {
        "_version": "1.1.0",
        "technology": "UI5",
        "deviceTypes": 
        {
            "desktop": true,
            "tablet": true,
            "phone": true
        },

        "supportedThemes": 
        [
            "sap_bluecrystal"
        ]
    },

    "sap.ui5": 
    {
        "_version": "1.1.0",
        "rootView": "ca.toronto.rcsmls.webapp.view.App",
        "dependencies": 
        {
            "minUI5Version": "1.30",
            "libs": 
            {
                "sap.m": 
                {

                }
            }
        },

        "config": 
        {
            "authenticationService": "http://172.21.226.138:9080/RcsMlsSvc/jaxrs/user/authenticate/",
            "assignedWorkService": "http://172.21.226.138:9080/RcsMlsSvc/jaxrs/mls/searchAssignedWork"
        },

        "models": 
        {
            "i18n": 
            {
                "type": "sap.ui.model.resource.ResourceModel",
                "settings": 
                {
                    "bundleName": "ca.toronto.rcsmls.webapp.i18n.i18n"
                }
            }
        },

        "routing": 
        {
            "config": 
            {
                "routerClass": "sap.m.routing.Router",
                "viewType": "XML",
                "viewPath": "ca.toronto.rcsmls.webapp.view",
                "controlId": "root",
                "controlAggregation": "pages"
            },

            "routes": 
            [
                {
                    "pattern": "",
                    "name": "login",
                    "target": "login"
                },
                {
                    "pattern": "work",
                    "name": "work",
                    "target": "work"
                }
            ],

            "targets": {
                "login": {
                    "viewName": "Login"
                },
                "work": {
                    "viewName": "Work"
                }
            }
        },

        "resources": 
        {
            "css": 
            [
                {
                    "uri": "css/style.css"
                }
            ]
        }
    }
}

app.json模型

代码语言:javascript
复制
{
    "BaseURL": "https://smp-pNNNNNNtrial.hanatrial.ondemand.com",
    "ES1Root": "https://sapes1.sapdevcenter.com",
    "AppName": "qmacro.myfirst",
    "Username": "yourusername",
    "Password": "yourpassword"
}

我找到了一个核心绑定工作的例子,这里。这是一个简单得多的应用程序。我还在努力找出这个项目和我的项目之间的区别

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-01-13 03:29:19

Github上有一个类似的问题使我意识到了这个问题

默认情况下,UI5组件不会从它们的环境(放置它们的ComponentContainer )继承模型和绑定上下文。这样做是为了与世隔绝。

可以通过设置容器的属性propagateModel:true来更改该默认行为:

代码语言:javascript
复制
new sap.ui.core.ComponentContainer({
  name: "ca.toronto.rcsmls.webapp.Component",
  propagateModel: true
}).placeAt("content");

propagateModel的文档可以在API参考中找到,也可以在UI5 开发人员指南中找到(后一页中的相应段落是最近才添加的,当您提出问题时它是不可用的)。

但是,当在组件的作用域中创建模型并在组件内部使用时,不应该需要将其添加到Core中。只需将其分配给组件,以便在该组件内的视图之间共享它:

从视图控制器中的某个方法分配它。

代码语言:javascript
复制
onInit : function() {
    this.getOwnerComponent().setModel(
        new sap.ui.model.json.JSONModel(
            "webapp/controller/app.json"), "app");
}

或者在Component.js本身的init过程中

代码语言:javascript
复制
init : function() {
    // create and set model to make it available to all views
    this.setModel(
        new sap.ui.model.json.JSONModel(
            "webapp/controller/app.json"), "app");

    // never forget to call init of the base class
    UIComponent.init.apply(this, arguments);
}

最现代的方法是在manifest.json中配置模型,并让框架实例化它。有关示例,请参见演练教程-步骤10:应用程序描述符

使用这些方法中的任何一种,都不应该需要在另一个视图中读取和设置模型,只要该视图是组件的后代(createContent返回的控件树的一部分)。

票数 4
EN

Stack Overflow用户

发布于 2015-12-08 22:02:51

我也经历过同样的行为。如果我创建一个简单的单文件应用程序,没有任何复杂的UI元素,基于核心的绑定就像一种魅力。

如果我创建一个复杂的容器,比如带有shell的App,这种绑定将不再有效。这些容器似乎从视图中隐藏了全局模型。

作为解决办法,我使用了以下代码片段:

代码语言:javascript
复制
this.getView().setModel(sap.ui.getCore().getModel(modelName), "modelName");

或者甚至可以将模型直接绑定到要使用的控件。

如果您必须在多个视图/控件中使用全局模型,那么它们都不是最好的解决方案,但这对我来说是有效的。

票数 1
EN

Stack Overflow用户

发布于 2015-12-08 22:02:14

在上面的视图中,只有密码字段的占位符使用您的应用程序模型。如果未正确填充此占位符,则无法加载json文件或内容与您在视图中使用的用于password字段占位符属性的绑定路径不匹配。若要了解更多信息,请同时发布json文件的内容。它看起来应该是这样的:

代码语言:javascript
复制
{ "Password" : "Enter your password", ... }

因此,根据视图中的绑定,数据对象的根级必须有"Password“属性。

下面,您可以找到一个运行中的示例,可以帮助您。正如你所看到的,它的工作就像一个魅力,所以你可以很容易地将一个命名的模型放到核心上,并在你的视图中引用它。

代码语言:javascript
复制
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>SAPUI5 single file template | nabisoft</title>
        <script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
            id="sap-ui-bootstrap"
            data-sap-ui-theme="sap_bluecrystal"
            data-sap-ui-libs="sap.m"
            data-sap-ui-bindingSyntax="complex"
            data-sap-ui-compatVersion="edge"
            data-sap-ui-preload="async"></script>
            <!-- use "sync" or change the code below if you have issues -->

        <!-- XMLView -->
        <script id="myXmlView" type="ui5/xmlview">
            <mvc:View
                controllerName="MyController"
                xmlns="sap.m"
                xmlns:core="sap.ui.core"
                xmlns:l="sap.ui.layout"
                xmlns:mvc="sap.ui.core.mvc">
                <App>
                    <Page title="My Page Title">
                        <content>
                            <Panel id="loginPanel" busyIndicatorDelay="0"
                                headerText="My Login Panel Title" class="sapUiResponsiveMargin loginPanel"
                                width="auto">
                                <l:VerticalLayout width="100%">

                                    <Input type="Text" placeholder="{Enter User ID}" value="{/mlsUser/uid}" />

                                    <Input type="Password" placeholder="{app>/Password}" value="{/mlsUser/password}" />

                                    <Button text="{Login}" press="doLogin" class="sapUiSmallMarginEnd customBold" width="100%" />

                                </l:VerticalLayout>
                            </Panel>
                        </content>
                    </Page>
                </App>
            </mvc:View>
        </script>

        <script>
            sap.ui.getCore().attachInit(function () {
                "use strict";

                //### Controller ###
                sap.ui.controller("MyController", {
                    onInit : function () {
                        var oData, oModel;

                        // 1. app model is only used for the placeholder field in the view
                        oData = {
                            Password : "Enter your password"
                        };
                        oModel = new sap.ui.model.json.JSONModel(oData);
                        sap.ui.getCore().setModel(oModel, "app");

                        // 2. default model is used in the view as well
                        oData = {
                            mlsUser : {},
                            Login : "Login now"
                        };
                        oModel = new sap.ui.model.json.JSONModel(oData);
                        sap.ui.getCore().setModel(oModel);

                        // 3. we need this because of the relative binding
                        //    of the text property of the login button
                        this.getView().bindElement("/");

                    }
                });

                //### THE APP: place the XMLView somewhere into DOM ###
                sap.ui.xmlview({
                    viewContent : jQuery("#myXmlView").html()
                }).placeAt("content");

            });
        </script>

    </head>

    <body class="sapUiBody">
        <div id="content"></div>
    </body>
</html>

在这个线程中,有些人提到"sap.ui.getCore()可以处理一些小东西,但不管出于什么原因,在更复杂的应用程序中不起作用“。

@Marc还发布了指向API文档的右链接,您可以在这里找到以下内容:

只有当ManagedObject是UIArea的后代时,它才会从核心继承模型

当然,您必须知道这意味着什么,这样才能编写符合您预期的代码。这里有一个小例子,告诉你,如果你有一个小小的“误解”,可能会发生什么(见下文)。

下面的代码创建了两个sap.m.Text实例,并将它们的文本属性绑定到一个JSONModel,它可以作为一个命名模型直接在Core上使用(用sap.ui.getCore()检索)。有两个按钮,每个sap.m.Text实例一个。在按钮的相应按下处理程序中,我只显示相应sap.m.Text实例的text属性。如您所见,两个sap.m.Text实例都绑定到JSONModel中的相同属性。但是,只有第二个sap.m.Text被添加到DOM中。

现在,有趣的部分可能与这个线程的混淆有关:只有第二个sap.m.Text控件的text属性包含来自JSONModel的预期文本"Hello“。第一个sap.m.Text控件的text属性没有来自模型的值"Hello“!这是SAPUI5的预期行为,并已记录在案!所以我想,如果你在自己的“复杂”应用程序中遇到了类似的问题,那么你很可能很难找到与这种“预期”行为相关的bug。

代码语言:javascript
复制
<!DOCTYPE html>
<html>
    <head>
        <meta charset="utf-8">
        <title>SAPUI5 single file template | nabisoft</title>
        <script src="https://openui5.hana.ondemand.com/resources/sap-ui-core.js"
            id="sap-ui-bootstrap"
            data-sap-ui-theme="sap_bluecrystal"
            data-sap-ui-libs="sap.m"
            data-sap-ui-bindingSyntax="complex"
            data-sap-ui-compatVersion="edge"
            data-sap-ui-preload="async"></script>
            <!-- use "sync" or change the code below if you have issues -->

        <script>
            sap.ui.getCore().attachInit(function () {

                sap.ui.define([
                    "sap/m/Text",
                    "sap/m/Button",
                    "sap/ui/model/json/JSONModel"
                ], function (Text, Button, JSONModel) {
                    "use strict";

                    var oModel = new JSONModel({
                        hello : "Hello World"
                    });
                    sap.ui.getCore().setModel(oModel, "core");

                    // not in DOM
                    var oText1 = new Text({
                        text : "{core>/hello}"
                    });
                    //oText1.placeAt("text1");      // uncomment this to enable the binding

                    // add to DOM
                    var oText2 = new Text({
                        text : "{core>/hello}"
                    });
                    oText2.placeAt("text2");

                    // action buttons to display text property of text controls
                    new Button({
                        text : "show oText1",
                        press : function(){
                            alert("oText1.getText() = " + oText1.getText());
                        }
                    }).placeAt("btn1");

                    new Button({
                        text : "show oText2",
                        press : function(){
                            alert("oText2.getText() = " + oText2.getText());
                        }
                    }).placeAt("btn2");

                });
            });
        </script>

    </head>

    <body class="sapUiBody">
        <div id="text1"></div>
        <div id="text2"></div>
        <span id="btn1"></span>
        <span id="btn2"></span>
    </body>
</html>

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34164430

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档