我有一个包含多个过滤项的过滤栏,我需要在 onSearch 事件中获取每个过滤项的选定/键入的值。我已经尝试过,但无法找到一种获取所有过滤器项目的所有过滤器数据的方法。
<fb:FilterBar reset="onReset"
search="onSearchFilterbar"
showRestoreButton="true"
showClearButton="true"
filterBarExpanded="false"
id="userFilterBar">
<fb:filterItems>
<fb:FilterItem name="A" label="User">
<fb:control>
<Select id="slcUser" forceSelection="false"
items="{ path: 'sysusers>/Users' , sorter: { path: 'Name' } }" >
<core:Item key="{sysusers>Name}" text="{sysusers>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
<fb:FilterItem name="B" label="Location">
<fb:control>
<Select id="slcLocation" forceSelection="false"
items="{ path: 'location>/Locations' , sorter: { path: 'Name' } }">
<core:Item key="{location>Name}" text="{location>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
</fb:filterItems>
</fb:FilterBar>
onsearch:function(oEvent){
oEvent.getSource().getFilterItems()[0];
// But cannot find a way to get the selected data
}
有几种方法可以做到这一点。 IMO,最好的方法是使用模型。这就是采用 MVC 方法。这是一个工作示例,http://jsbin.com/nudewew/edit?html,output
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="X-UA-Compatible" content="IE=edge" />
<meta charset="UTF-8">
<title>MVC</title>
<script id="sap-ui-bootstrap" type="text/javascript"
src="https://sapui5.hana.ondemand.com/resources/sap-ui-core.js"
data-sap-ui-theme="sap_bluecrystal"
data-sap-ui-libs="sap.m,sap.ui.table"
data-sap-ui-xx-bindingSyntax="complex">
</script>
<script id="oView" type="sapui5/xmlview">
<mvc:View height="100%" controllerName="myView.Template"
xmlns="sap.m"
xmlns:fb="sap.ui.comp.filterbar"
xmlns:core="sap.ui.core"
xmlns:mvc="sap.ui.core.mvc">
<fb:FilterBar reset="onReset"
search="onSearchFilterbar"
showRestoreButton="true"
showClearButton="true"
filterBarExpanded="false"
id="userFilterBar">
<fb:filterItems>
<fb:FilterItem name="A" label="User">
<fb:control>
<Select id="slcUser" forceSelection="false" selectedKey="{selection>/user}"
items="{ path: 'sysusers>/Users' , sorter: { path: 'Name' } }" >
<core:Item key="{sysusers>Name}" text="{sysusers>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
<fb:FilterItem name="B" label="Location">
<fb:control>
<Select id="slcLocation" forceSelection="false" selectedKey="{selection>/location}"
items="{ path: 'location>/Locations' , sorter: { path: 'Name' } }">
<core:Item key="{location>Name}" text="{location>Name}"/>
</Select>
</fb:control>
</fb:FilterItem>
</fb:filterItems>
</fb:FilterBar>
</mvc:View>
</script>
<script>
sap.ui.define([
'jquery.sap.global',
'sap/ui/core/mvc/Controller',
'sap/ui/model/json/JSONModel'
], function(jQuery, Controller, JSONModel) {
"use strict";
var oController = Controller.extend("myView.Template", {
onInit: function() {
var oView = this.getView();
oView.setModel(new JSONModel({
user: "",
location: ""
}), "selection");
oView.setModel(new JSONModel({
Users: [
{Name: "johnDoe"},
{Name: "maryAnn"}
]
}), "sysusers");
oView.setModel(new JSONModel({
Locations: [
{Name: "London"},
{Name: "Paris"}
]
}), "location");
},
onSearchFilterbar: function(oEvent) {
console.log(this.getView().getModel("selection").getData());
}
});
return oController;
});
var oView = sap.ui.xmlview({
viewContent: jQuery('#oView').html()
});
oView.placeAt('content');
</script>
</head>
<body class="sapUiBody" role="application">
<div id="content"></div>
</body>
</html>
项目的值在事件的参数中。
oEvent.getParameter('0').selectionSet
这是一个数组,其中每个
filterbar
控件都可以使用:
oEvent.getParameter('0').selectionSet[0].getValue()
有几种方法可以做到这一点..但是对于您当前的代码,我建议如下:
您问题的简短回答:
FilterBar 有一个方法
determineControlByFilterItem
,您可以使用它来获取过滤器项目的控件,然后您可以使用该方法来获取选定的值。
var oFilterItem = oEvent.getSource().getFilterItems()[0];
var oControl = oFilterBar.determineControlByFilterItem(oFilterItem);
var sSelectedValue = oControl.getSelectedKey();
但是,在像这样对数组索引进行硬编码时要小心。为了更完整地解决您的问题,我在下面建议了完整的方法。
如果您想使用过滤栏来过滤结果集,请长回答:
首先,确保过滤项的名称与您要过滤的属性的名称对齐。因此,在您的情况下,您的过滤器项目被命名为“A”和“B”...我建议您更改这些以匹配您要过滤的属性名称。假设您要过滤的属性名称是“用户”和“位置”:
<FilterItem name="User" label="User">
...
<FilterItem name="Location" label="Location">
...
然后在控制器中,您可以使用这些名称来构建
sap.ui.model.Filter
对象数组,您可以使用它们来过滤结果集。
onSearch: function(oEvent) {
//get the filter bar from the event
var oFilterBar = oEvent.getSource();
//get the filter items from the filter bar
var aFilterItems = oFilterBar.getFilterItems();
//map the array of FilterItems to a new array of sap.ui.model.Filter objects
var aFilters = aFilterItems.map(function(oFilterItem) {
//get the filter item name (which is now the same as the filter property name)
var sFilterName = oFilterItem.getName();
//use the filter bar to get the control for the filter item
var oControl = oFilterBar.determineControlByFilterItem(oFilterItem);
//use the control to get the selected value (selected key)
var sSelectedValue = oControl.getSelectedKey();
//use the filter item/property name and the selected value to create a new sap.ui.model.Filter
var oFilter = new sap.ui.model.Filter(sFilterName, "EQ", sSelectedValue);
//return the Filter object to the new array
return oFilter
});
//use the array of sap.ui.model.Filter objects to filter your table
//if you're using a responsive table (sap.m.Table), use:
this.getView().byId("yourTableId").getBinding("items").filter(aFilters);
//or if you're using a grid table (sap.ui.table.Table), use:
this.getView().byId("yourTableId").getBinding("rows").filter(aFilters);
}
我之所以建议这种方法而不是其他方法,是因为它的扩展性很好。例如,假设您想要添加第三个
Select
控件作为过滤依据,您只需添加一个新的 <FilterItem name="NewFilterProperty" label="New Filter Property">
即可。因为我们没有将任何内容硬编码到事件处理程序中,所以它仍然可以工作,无需任何额外的更改。
唯一需要注意的是您是否在 FilterBar 中使用不同类型的控件。因此,例如,如果您添加了
<Input>
而不是 <Select>
,则需要调整事件处理程序的逻辑来处理此问题。
我通常会做这样的事情:
onSearch: function(oEvent) {
var oFilterBar = oEvent.getSource();
var aFilterItems = oFilterBar.getFilterItems();
var aFilters = aFilterItems.map(function(oFilterItem) {
var sFilterName = oFilterItem.getName();
var oControl = oFilterBar.determineControlByFilterItem(oFilterItem);
var sValue;
if (oControl.getMetadata().getName() === "sap.m.Select") {
sValue = oControl.getSelectedKey();
} else if (oControl.getMetadata().getName() === "sap.m.Input") {
sValue = oControl.getValue();
}
var oFilter = new sap.ui.model.Filter(sFilterName, "EQ", sValue);
return oFilter;
});
}