SAPUI5 (08) - MVC的Model和数据绑定

前面的MVC介绍只有view和controller,还没有涉及数据,所以没有model的部分。本篇增加数据,介绍Model以及数据绑定,展示一个完整的MVC示例。我们将要实现的示例是在页面中显示供应商的列表,每个供应商含有ID和Name两个字段。

首先介绍几个相关的知识点。因为我们打算在表格(Table)中显示供应商,所以我们选择sap.ui.table.Table控件,这个控件对PC和Tablet有很好的适应,界面漂亮,功能强大。

知识点介绍

sap.ui.table.Table

官方参考

Table以行和列的方式显示数据,这种样式我相信大家都很熟悉,展示方法就像Excel,有行和列构成。本篇将使用sap.ui.table.Table的如下属性:

width : sap.ui.core.CSSSize (default: auto)。表格的宽度可以是百分百,或者基于像素。
visibleRowCount : int (default: 10)。默认显示10行,可以自定义。
firstVisibleRow : int (default: 0)
selectionMode : sap.ui.table.SelectionMode (default: MultiToggle)。包括单行(sap.ui.table.SelectionMode.Single)、多行(sap.ui.table.SelectionMode.MultiToggle)和不能选择行(sap.ui.table.SelectionMode.None)。
editable : boolean (default: true)。默认可以编辑,如果只是显示,将此属性设置为false。

Table的聚合(Aggregation):

title : sap.ui.core.Control|string
columns : sap.ui.table.Column[] (default)

sap.ui.table.Column

官方参考

定义Table的列。本篇要用到的属性:

width : sap.ui.core.CSSSize
sortProperty : string。指定按哪个字段进行排序。

聚合:

label : sap.ui.core.Control|string (default)
template : sap.ui.core.Control。template聚合属性是一个控件,通过控件来绑定数据。

Models

MVC的Model代表应用程序的数据,如果数据来自客户端(client),有JSON model、XML model和Resource model三种; 如果数据来自服务器端(server),有oData model。不管这些数据来自何处,sapui5都需要进行加载和使用。我们第一个例子,使用JSON model,JSON数据采取硬编码方式。为了方便介绍,先贴出完整代码。

不用MVC方式的代码

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>

        <script src="resources/sap-ui-core.js"
                id="sap-ui-bootstrap"
                data-sap-ui-libs="sap.m, sap.ui.table"
                data-sap-ui-theme="sap_bluecrystal">
        </script>

        <script>
            // application data
            var oAppData = 
            {
                "CountSuppliers" : 2,
                "Suppliers" : [{
                        "ID": 1,
                        "Name": "中国图书进出口公司"
                    }, {
                        "ID": 2,
                        "Name": "东莞少儿玩具制造厂"
                    }                   
                ]           
            };
            
            var oModel = sap.ui.model.json.JSONModel();
            oModel.setData(oAppData);
            
            // setting the model to the core
            // so that it's available to the whole application
            sap.ui.getCore().setModel(oModel);
            
            // define columns and table
            var oIdCol = new sap.ui.table.Column({
                label: new sap.m.Label({text:"ID"}),
                template: new sap.m.Text().bindProperty("text", "ID"),
                sortProperty: "ID",
                width: "100px"
            });
            
            var oNameCol = new sap.ui.table.Column({
                label: new sap.m.Label({text:"Name"}),
                template: new sap.m.Text().bindProperty("text", "Name"),
                sortProperty: "Name",
                width: "150px"
            });
            
            var oTable = new sap.ui.table.Table({
                width: "100%",
                title: "供应商列表",
                visibleRowCount: 2,
                firstVisibleRow: 0,
                editable: false,
                selectionMode: sap.ui.table.SelectionMode.Single,
                columns: [oIdCol, oNameCol]
            });
            
            oTable.setModel(oModel);
            oTable.bindRows("/Suppliers");  
            
            // define page & app
            var oPage = new sap.m.Page("masterpage", {  
                title: "供应商",
                content: [oTable]
            });
            
            var oApp = new sap.m.App("myApp");
            
            oApp.addPage(oPage);
            oApp.placeAt("content");            
            
        </script>

    </head>
    <body class="sapUiBody SapUiResponsiveMargin" role="application">
        <div id="content"></div>
    </body>
</html>

代码分为三个部分,第一个部分是定义JSON数据,并加载。JSON数据包含两个供应商的数据,每个供应商有ID和Name两个字段。var oModel = sap.ui.model.json.JSONModel();声明一个JSONModel,oModel.setData(oAppData);语句设置JSON model的数据为刚刚定义的JSON数据;sap.ui.getCore().setModel(oModel);语句设置core对象的Model为oModel,这样oModel对整个应用程序可见。

第二部分是声明sap.ui.Table类的对象,以及绑定数据。

            // define columns and table
            var oIdCol = new sap.ui.table.Column({
                label: new sap.m.Label({text:"ID"}),
                template: new sap.m.Text().bindProperty("text", "ID"),
                sortProperty: "ID",
                width: "100px"
            });
            
            var oNameCol = new sap.ui.table.Column({
                label: new sap.m.Label({text:"Name"}),
                template: new sap.m.Text().bindProperty("text", "Name"),
                sortProperty: "Name",
                width: "150px"
            });
            
            var oTable = new sap.ui.table.Table({
                width: "100%",
                title: "供应商列表",
                visibleRowCount: 2,
                firstVisibleRow: 0,
                editable: false,
                selectionMode: sap.ui.table.SelectionMode.Single,
                columns: [oIdCol, oNameCol]
            });
            
            oTable.setModel(oModel);
            oTable.bindRows("/Suppliers");  

先定义两个sap.ui.table.Column对象,sap.ui.table.Column对象的template设置为sap.m.Text对象,并与JSON model的ID和Name两列绑定。我们暂且不用管数据绑定的细节,后面会详细介绍。

var oTable = ...语句声明一个sap.ui.table.Table对象,Table包含刚刚申明的两个列对象。

oTable.setModel(oModel);实现Table与JSONModel的绑定,也就是View和Model的绑定。oTable.bindRows("/Suppliers");语句实现Table与JSON数据的绑定,JSON数据是层次化的数据,如本例,JSON数据的根目录下有两个值:CountSuppliers和Suppliers,Table绑定Suppliers

第三个部分代码就是申明App和Page,不多说。程序运行界面:

MVC实现

仍然使用javascript view。项目的文件结构如下:

项目文件结构

index.html

<!DOCTYPE HTML>
<html>
    <head>
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <meta http-equiv='Content-Type' content='text/html;charset=UTF-8'/>

        <script src="resources/sap-ui-core.js"
                id="sap-ui-bootstrap"
                data-sap-ui-libs="sap.m, sap.ui.table"
                data-sap-ui-theme="sap_bluecrystal">
        </script>

        <script>
            jQuery.sap.registerModulePath("suppliers", "./suppliers");
                        
            var oApp = new sap.m.App({initialPage: "firstPage"});
            var oFirstPage = sap.ui.view({
                id: "firstPage",
                viewName: "suppliers.supplieroverview",
                type: "JS"
            });             
            
            oApp.addPage(oFirstPage);
            oApp.placeAt("content");
        </script>

    </head>
    <body class="sapUiBody SapUiResponsiveMargin" role="application">
        <div id="content"></div>
    </body>
</html>
  • jQuery.sap.registerModulePath("suppliers", "./suppliers");将suppliers注册为当前文件夹下的suppliers子文件夹。

  • 定义一个sap.m.Appsap.ui.view,view加载到App,App放置在div中。

suppliers.json

将json数据放在一个单独的文件中,文件内容如下:

{
    "CountSuppliers" : 2,
    "Suppliers" : [{
            "ID": 1,
            "Name": "中国图书进出口公司"
        }, {
            "ID": 2,
            "Name": "东莞少儿玩具制造厂"
        }                   
    ]           
}

supplieroverview.view.js

sap.ui.jsview("suppliers.supplieroverview", {

    /** Specifies the Controller belonging to this View. 
    * In the case that it is not implemented, or that "null" is returned, this View does not have a Controller.
    * @memberOf suppliers.supplieroverview
    */ 
    getControllerName : function() {
        return "suppliers.supplieroverview";
    },

    /** Is initially called once after the Controller has been instantiated. It is the place where the UI is constructed. 
    * Since the Controller is given to this method, its event handlers can be attached right away. 
    * @memberOf suppliers.supplieroverview
    */ 
    createContent : function(oController) {
        // define columns and table
        var oColumns = [
            new sap.ui.table.Column({
                label: new sap.m.Label({text:"ID"}),
                template: new sap.m.Text().bindProperty("text", "ID"),
                sortProperty: "ID",
                width: "50px"
            }),
            new sap.ui.table.Column({
                label: new sap.m.Label({text:"Name"}),
                template: new sap.m.Text().bindProperty("text", "Name"),
                sortProperty: "ID",
                width: "100px"
            })
        ];  
        
        var oTable = new sap.ui.table.Table({
            width: "100%",
            title: "供应商列表",
            visibleRowCount: 2,
            firstVisibleRow: 0,
            editable: false,
            selectionMode: sap.ui.table.SelectionMode.Single,
            columns: oColumns
        });         

        oTable.bindRows("/Suppliers");      
        
        var oPage = new sap.m.Page({
            title: "供应商",
            content: [oTable]
        });
        
        return oPage;
    }
    
});

每个javascript view都有getControllerNamecreateContent两个函数。显示的内容写在createContent函数中。主要结构如下:

var oColumns = ...;
var oTable = new sap.ui.table.Table({...});
oTable.bindRows("/Suppliers");

var oPage = new sap.m.Page({content: [oTable]});

return oPage;

supplieroverview.controller.js

sap.ui.controller("suppliers.supplieroverview", {

/**
* Called when a controller is instantiated and its View controls (if available) are already created.
* Can be used to modify the View before it is displayed, to bind event handlers and do other one-time initialization.
* @memberOf suppliers.supplieroverview
*/
    onInit: function() {        
        var oModel = sap.ui.model.json.JSONModel('models/suppliers.json');          
        this.getView().setModel(oModel);
    }
});

sap.ui.core.mvc.Controller对象的getView()方法获得与之关联的View,然后设置View与Model的关联。

今天是2017年第一天,坚持!

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 206,482评论 6 481
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 88,377评论 2 382
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 152,762评论 0 342
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 55,273评论 1 279
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 64,289评论 5 373
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 49,046评论 1 285
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 38,351评论 3 400
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,988评论 0 259
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 43,476评论 1 300
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,948评论 2 324
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 38,064评论 1 333
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,712评论 4 323
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 39,261评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 30,264评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,486评论 1 262
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 45,511评论 2 354
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,802评论 2 345

推荐阅读更多精彩内容