UI5:从具有不同图标的 JSON 动态构建 ListItems

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/28586513/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-03 17:45:56  来源:igfitidea点击:

UI5: Dynamically build ListItems from JSON with different Icons

jsondata-bindinglistitemsapui5

提问by ho.s

I have this simple XML View:

我有这个简单的 XML 视图:

<core:View xmlns:core="sap.ui.core" xmlns:mvc="sap.ui.core.mvc" xmlns="sap.m"
        controllerName="listicons.list" xmlns:html="http://www.w3.org/1999/xhtml">
    <Page title="Title">
        <content>
            <List id="test-list"></List>
        </content>
    </Page>
</core:View>

In my controller, I call a method to build list items onInit. First of all set some data:

在我的控制器中,我调用了一个方法来在 Init 上构建列表项。首先设置一些数据:

var data = {
        "products": [
              {
                  "prodName": "Apple",
                  "prodCountry": "Netherlands",
                  "price": "normal"
              },
              {
                  "prodName": "Orange",
                  "prodCountry": "Spain",
                  "price": "extra"
              },
              {
                  "prodName": "Strawberry",
                  "prodCountry": "Poland",
                  "price": "normal"
              }
          ]
        };
// create a Model with this data and attach it to the view
            var model = new sap.ui.model.json.JSONModel();
            model.setData(data);
            this.getView().setModel(model);
            var list = this.getView().byId("test-list");

Then I build the list and bind the items to it:

然后我构建列表并将项目绑定到它:

// bind the List items to the data collection
            list.bindItems({
                path : "/products", 
                sorter : new sap.ui.model.Sorter("prodName"),
                //template : listTmpl
                template : new sap.m.StandardListItem({
                    title: "{prodName}",
                    description: "{prodCountry}"
                })
            }); 

After I built the list and is alread rendered, I look after which items have an extra price and set an icon for them:

在我建立了清单并已经呈现之后,我会查看哪些物品有额外的价格并为它们设置一个图标:

jQuery.each(list.getItems(), function(i, obj) {
                if(obj.mProperties.price == "extra") {
                    obj.setIcon("sap-icon://flag"); 
                }
            });

So. Everything works fine. But I am not happy with my solution, because I'd rather like to manipulate the data BEFORE rendering the list. I tried to build a list template directly before binding the items to the list and then use this template like:

所以。一切正常。但是我对我的解决方案并不满意,因为我更愿意在呈现列表之前操作数据。我尝试在将项目绑定到列表之前直接构建一个列表模板,然后使用此模板,例如:

var listTmpl = jQuery.each(data.products, function(i, a) {
            var lI = new sap.m.StandardListItem({
                title: "{prodName}",
                description: "{prodCountry}" 
            });
            if(a.price == "extra") {
                lI.setIcon("sap-icon://flag");
            }
            return lI;
        });

But then my list is not shown and I got an error in the console, saying

但是后来我的列表没有显示,我在控制台中收到一个错误,说

Missing template or factory function for aggregation items of Element sap.m.List ...

缺少元素 sap.m.List 聚合项的模板或工厂函数...

Does anyone have an idea how to improve my sol.? THX a lot..

有谁知道如何改善我的溶胶。?多谢..

回答by herrlock

bind the value for price to a formatter-function. so you can create the icons dynamically from the value

将价格的值绑定到格式化函数。所以你可以从值动态创建图标

list.bindItems({
    path : "/products", 
    sorter : new sap.ui.model.Sorter("prodName"),
    template : new sap.m.StandardListItem({
        title: "{prodName}",
        description: "{prodCountry}",
        /* bind items to factory-function */
        icon: {
            path: "price",
            formatter: function(price) {
                if (price == "extra") {
                    return "sap-icon://flag"; 
                }
            }
        }
    })
}); 

ps: i did not test this, but it should work like this. if you receive errors just comment.

ps:我没有测试这个,但它应该像这样工作。如果您收到错误,请发表评论。

回答by Qualiture

IMHO, I think you can have the controller as clean as possible, and define most of the needed functionality (binding, template, sorter, and icon) in the XMLView:

恕我直言,我认为您可以让控制器尽可能干净,并在 XMLView 中定义大部分所需的功能(绑定、模板、排序器和图标):

<List id="test-list" items="{
    path   : '/products', 
    sorter : [{
        path       : 'prodName', 
        descending : true
    }]
}">
    <StandardListItem title="{prodName}" 
                      description="{prodCountry}" 
                      icon="{path:'price', formatter:'.getIconFlag'}" />
</List>

You then can rid of allthe template binding and manipulation stuff you have in your controller, and you only need to specify the formatter function getIconFlag:

然后,您可以删除控制器中的所有模板绑定和操作内容,您只需要指定格式化程序函数getIconFlag

getIconFlag : function (sPrice) {
    return sPrice === "extra" ? "sap-icon://flag" : null;
}

See the following working example:

请参阅以下工作示例:

sap.ui.controller("view1.initial", {
    onInit : function(oEvent) {
        var oModel = new sap.ui.model.json.JSONModel();
        oModel.setData({
            "products": [
                {
                    "prodName": "Apple",
                    "prodCountry": "Netherlands",
                    "price": "normal"
                },
                {
                    "prodName": "Orange",
                    "prodCountry": "Spain",
                    "price": "extra"
                },
                {
                    "prodName": "Strawberry",
                    "prodCountry": "Poland",
                    "price": "normal"
                }
            ]
        });

        this.getView().setModel(oModel);

    },

    getIconFlag : function (sPrice) {
        return sPrice === "extra" ? "sap-icon://flag" : null;
    }

});

sap.ui.xmlview("main", {
    viewContent: jQuery("#view1").html()
})
.placeAt("uiArea");
<script id="sap-ui-bootstrap"
    src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
    data-sap-ui-theme="sap_bluecrystal"
    data-sap-ui-xx-bindingSyntax="complex"
    data-sap-ui-libs="sap.m"></script>

<div id="uiArea"></div>

<script id="view1" type="ui5/xmlview">
    <mvc:View 
      controllerName="view1.initial"
      xmlns="sap.m"
      xmlns:core="sap.ui.core"
      xmlns:mvc="sap.ui.core.mvc" >
        <List id="test-list" items="{
            path: '/products', 
            sorter: [{
                path: 'prodName', 
                descending: true
            }]
        }">
            <StandardListItem title="{prodName}" description="{prodCountry}" icon="{path:'price', formatter:'.getIconFlag'}" />
        </List>
    </mvc:View>
</script>