Odata 如何搜索sap.m.树中的所有节点?

Odata 如何搜索sap.m.树中的所有节点?,odata,sapui5,Odata,Sapui5,我目前正在为我的公司开发一个MasterDetail应用程序,该应用程序提供以节点表示的可扩展类别 节点及其子节点与导航属性的绑定不是问题。但是,如果我想在上面的搜索字段中搜索某个组节点,它只在最高的四个节点之间进行过滤。它可以搜索第一级上的节点,但如果节点低于第一级,则无法找到节点 树的绑定: <Tree selectionChange="onSelectionChange" id="list" noDataText=&q

我目前正在为我的公司开发一个MasterDetail应用程序,该应用程序提供以节点表示的可扩展类别

节点及其子节点与导航属性的绑定不是问题。但是,如果我想在上面的搜索字段中搜索某个组节点,它只在最高的四个节点之间进行过滤。它可以搜索第一级上的节点,但如果节点低于第一级,则无法找到节点

树的绑定:

<Tree
    selectionChange="onSelectionChange"
    id="list"
    noDataText="{masterView>/noDataText}"
    busyIndicatorDelay="{masterView>/delay}"
    items="{path: '/GroupNodes',
                parameters : {
                expand: 'ChildGroupNodes',
                navigation: {
                    'GroupNodes': 'ChildGroupNodes'
                    }
            }
    }">
    <StandardTreeItem 
        title="{Stext}"
        type="Navigation"
        press="onSelectionChange"/>
</Tree>
    onSearch: function(oEvent) {
        if (oEvent.getParameters().refreshButtonPressed) {
            this.onRefresh();
            return;
        }

        var sQuery = oEvent.getParameter("query");
        if (sQuery) {
            this._oListFilterState.aSearch = [new Filter("Stext", FilterOperator.Contains, sQuery)];
        } else {
            this._oListFilterState.aSearch = [];
        }
        this._applyFilterSearch();
    },
    _applyFilterSearch: function() {
        var aFilters = this._oListFilterState.aSearch.concat(this._oListFilterState.aFilter),
            oViewModel = this.getModel();

        this._oList.getBinding("items").filter(aFilters, "Application");
        
        if (aFilters.length !== 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataWithFilterOrSearchText"));
        } else if (this._oListFilterState.aSearch.length > 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataText"));
        }
    },
this._oListFilterState = {
    aFilter: [],
    aSearch: []
};
<EntityType Name="GroupNode" sap:content-version="1">
      <Key>
         <PropertyRef Name="Grpid"/>
      </Key>
      <Property Name="Grpid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="Id Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Short" Type="Edm.String" MaxLength="12" sap:unicode="false" sap:label="Kürzel Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Stext" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Bezeichnung Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Begda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Beginndatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Endda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Endedatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Level" Type="Edm.Int32" sap:unicode="false" sap:label="Level" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Parentid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="ParentId" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <NavigationProperty Name="ChildGroupNodes" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupNodeToParent" FromRole="FromRole_GroupNodeToParent" ToRole="ToRole_GroupNodeToParent"/>
      <NavigationProperty Name="GroupToTrainingType" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupToTrainingType" FromRole="FromRole_GroupToTrainingType" ToRole="ToRole_GroupToTrainingType"/>
</EntityType>
\u应用过滤器搜索:

<Tree
    selectionChange="onSelectionChange"
    id="list"
    noDataText="{masterView>/noDataText}"
    busyIndicatorDelay="{masterView>/delay}"
    items="{path: '/GroupNodes',
                parameters : {
                expand: 'ChildGroupNodes',
                navigation: {
                    'GroupNodes': 'ChildGroupNodes'
                    }
            }
    }">
    <StandardTreeItem 
        title="{Stext}"
        type="Navigation"
        press="onSelectionChange"/>
</Tree>
    onSearch: function(oEvent) {
        if (oEvent.getParameters().refreshButtonPressed) {
            this.onRefresh();
            return;
        }

        var sQuery = oEvent.getParameter("query");
        if (sQuery) {
            this._oListFilterState.aSearch = [new Filter("Stext", FilterOperator.Contains, sQuery)];
        } else {
            this._oListFilterState.aSearch = [];
        }
        this._applyFilterSearch();
    },
    _applyFilterSearch: function() {
        var aFilters = this._oListFilterState.aSearch.concat(this._oListFilterState.aFilter),
            oViewModel = this.getModel();

        this._oList.getBinding("items").filter(aFilters, "Application");
        
        if (aFilters.length !== 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataWithFilterOrSearchText"));
        } else if (this._oListFilterState.aSearch.length > 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataText"));
        }
    },
this._oListFilterState = {
    aFilter: [],
    aSearch: []
};
<EntityType Name="GroupNode" sap:content-version="1">
      <Key>
         <PropertyRef Name="Grpid"/>
      </Key>
      <Property Name="Grpid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="Id Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Short" Type="Edm.String" MaxLength="12" sap:unicode="false" sap:label="Kürzel Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Stext" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Bezeichnung Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Begda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Beginndatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Endda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Endedatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Level" Type="Edm.Int32" sap:unicode="false" sap:label="Level" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Parentid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="ParentId" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <NavigationProperty Name="ChildGroupNodes" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupNodeToParent" FromRole="FromRole_GroupNodeToParent" ToRole="ToRole_GroupNodeToParent"/>
      <NavigationProperty Name="GroupToTrainingType" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupToTrainingType" FromRole="FromRole_GroupToTrainingType" ToRole="ToRole_GroupToTrainingType"/>
</EntityType>
onInit()函数中的过滤器状态:

<Tree
    selectionChange="onSelectionChange"
    id="list"
    noDataText="{masterView>/noDataText}"
    busyIndicatorDelay="{masterView>/delay}"
    items="{path: '/GroupNodes',
                parameters : {
                expand: 'ChildGroupNodes',
                navigation: {
                    'GroupNodes': 'ChildGroupNodes'
                    }
            }
    }">
    <StandardTreeItem 
        title="{Stext}"
        type="Navigation"
        press="onSelectionChange"/>
</Tree>
    onSearch: function(oEvent) {
        if (oEvent.getParameters().refreshButtonPressed) {
            this.onRefresh();
            return;
        }

        var sQuery = oEvent.getParameter("query");
        if (sQuery) {
            this._oListFilterState.aSearch = [new Filter("Stext", FilterOperator.Contains, sQuery)];
        } else {
            this._oListFilterState.aSearch = [];
        }
        this._applyFilterSearch();
    },
    _applyFilterSearch: function() {
        var aFilters = this._oListFilterState.aSearch.concat(this._oListFilterState.aFilter),
            oViewModel = this.getModel();

        this._oList.getBinding("items").filter(aFilters, "Application");
        
        if (aFilters.length !== 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataWithFilterOrSearchText"));
        } else if (this._oListFilterState.aSearch.length > 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataText"));
        }
    },
this._oListFilterState = {
    aFilter: [],
    aSearch: []
};
<EntityType Name="GroupNode" sap:content-version="1">
      <Key>
         <PropertyRef Name="Grpid"/>
      </Key>
      <Property Name="Grpid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="Id Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Short" Type="Edm.String" MaxLength="12" sap:unicode="false" sap:label="Kürzel Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Stext" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Bezeichnung Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Begda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Beginndatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Endda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Endedatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Level" Type="Edm.Int32" sap:unicode="false" sap:label="Level" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Parentid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="ParentId" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <NavigationProperty Name="ChildGroupNodes" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupNodeToParent" FromRole="FromRole_GroupNodeToParent" ToRole="ToRole_GroupNodeToParent"/>
      <NavigationProperty Name="GroupToTrainingType" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupToTrainingType" FromRole="FromRole_GroupToTrainingType" ToRole="ToRole_GroupToTrainingType"/>
</EntityType>
元数据:

<Tree
    selectionChange="onSelectionChange"
    id="list"
    noDataText="{masterView>/noDataText}"
    busyIndicatorDelay="{masterView>/delay}"
    items="{path: '/GroupNodes',
                parameters : {
                expand: 'ChildGroupNodes',
                navigation: {
                    'GroupNodes': 'ChildGroupNodes'
                    }
            }
    }">
    <StandardTreeItem 
        title="{Stext}"
        type="Navigation"
        press="onSelectionChange"/>
</Tree>
    onSearch: function(oEvent) {
        if (oEvent.getParameters().refreshButtonPressed) {
            this.onRefresh();
            return;
        }

        var sQuery = oEvent.getParameter("query");
        if (sQuery) {
            this._oListFilterState.aSearch = [new Filter("Stext", FilterOperator.Contains, sQuery)];
        } else {
            this._oListFilterState.aSearch = [];
        }
        this._applyFilterSearch();
    },
    _applyFilterSearch: function() {
        var aFilters = this._oListFilterState.aSearch.concat(this._oListFilterState.aFilter),
            oViewModel = this.getModel();

        this._oList.getBinding("items").filter(aFilters, "Application");
        
        if (aFilters.length !== 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataWithFilterOrSearchText"));
        } else if (this._oListFilterState.aSearch.length > 0) {
            oViewModel.setProperty("/noDataText", this.getResourceBundle().getText("masterListNoDataText"));
        }
    },
this._oListFilterState = {
    aFilter: [],
    aSearch: []
};
<EntityType Name="GroupNode" sap:content-version="1">
      <Key>
         <PropertyRef Name="Grpid"/>
      </Key>
      <Property Name="Grpid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="Id Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Short" Type="Edm.String" MaxLength="12" sap:unicode="false" sap:label="Kürzel Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Stext" Type="Edm.String" MaxLength="40" sap:unicode="false" sap:label="Bezeichnung Trainingsgruppe" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <Property Name="Begda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Beginndatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Endda" Type="Edm.DateTime" Precision="0" sap:unicode="false" sap:label="Endedatum" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Level" Type="Edm.Int32" sap:unicode="false" sap:label="Level" sap:creatable="false" sap:updatable="false" sap:sortable="false" sap:filterable="false"/>
      <Property Name="Parentid" Type="Edm.String" Nullable="false" MaxLength="8" sap:unicode="false" sap:label="ParentId" sap:creatable="false" sap:updatable="false" sap:filterable="false"/>
      <NavigationProperty Name="ChildGroupNodes" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupNodeToParent" FromRole="FromRole_GroupNodeToParent" ToRole="ToRole_GroupNodeToParent"/>
      <NavigationProperty Name="GroupToTrainingType" Relationship="Z_HR_LSO_WORKCENTER_SRV.GroupToTrainingType" FromRole="FromRole_GroupToTrainingType" ToRole="ToRole_GroupToTrainingType"/>
</EntityType>

我们正在使用ODataV2,因此不可能实现FilterContains.All筛选器


甚至可以通过前端中sap.m.Tree的子节点进行过滤吗?

我认为这可能与您绑定项目的方式有关,因为在我的示例中,我可以使用您的JS在子节点上进行过滤

在执行筛选之前,请检查此._oList.getItems()中是否包含所有项

我将发布我的代码,这样您就可以重建我的项目并了解它是如何工作的。如果你有更多问题,请告诉我




Page.view.xml

  <mvc:View
    controllerName="sap.m.sample.Tree.Page"
    xmlns:mvc="sap.ui.core.mvc"
    xmlns="sap.m">
    <SearchField value="{json>/search}" search="onSearch"/>
        <Tree
            id="Tree"
            items="{path: '/'}">
            <StandardTreeItem title="{text}"/>
        </Tree>
</mvc:View>
Tree.json

[
{
    "text": "Node1",
    "ref": "sap-icon://attachment-audio",
    "nodes":
    [
        {
            "text": "Node1-1",
            "ref": "sap-icon://attachment-e-pub",
            "nodes":[
                {
                    "text": "Node1-1-1",
                    "ref": "sap-icon://attachment-html"
                },
                {
                    "text": "Node1-1-2",
                    "ref": "sap-icon://attachment-photo",
                    "nodes":[
                        {
                            "text": "Node1-1-2-1",
                            "ref": "sap-icon://attachment-text-file",
                            "nodes":[
                                {
                                    "text": "Node1-1-2-1-1",
                                    "ref": "sap-icon://attachment-video"
                                },
                                {
                                    "text": "Node1-1-2-1-2",
                                    "ref": "sap-icon://attachment-zip-file"
                                },
                                {
                                    "text": "Node1-1-2-1-3",
                                    "ref": "sap-icon://course-program"
                                }
                            ]
                        }
                    ]
                }
            ]
        },
        {
            "text": "Node1-2",
            "ref": "sap-icon://create"
        }
    ]
},
{
    "text": "Node2",
    "ref": "sap-icon://customer-financial-fact-sheet"
}
]

这就是你所需要的,但万一你也需要这些。。。 index.html

<!DOCTYPE HTML>

}))

我不确定你是否解决了你的问题,但事实上我几个月前就做了这件事

在控制器中,设置以下功能:

    onSearch: function(oEvent) {

        var searchVal = oEvent.getParameter("newValue");
        var treeFilter = new sap.ui.model.Filter("Text", sap.ui.model.FilterOperator.Contains, searchVal);
        var oBinding = this.getView().byId("tree").mBindingInfos.rows.binding;

        oBinding.filter(treeFilter, FilterType.Application);
        oBinding.expandToLevel(3);
    },
这应该马上就能奏效。无论您在搜索框中输入什么,它都将使用您的过滤器填充树(最多3个级别,但可以更改)


onSearch函数当然是在搜索字段的livechange上执行的。

以下是一个工作示例:

首先,通过导航属性构建树层次结构。SAP建议改为使用

重要提示:不推荐使用导航属性来构建层次结构,建议使用层次结构批注

完成到注释方法的迁移后,可以根据以下条件筛选树客户端:

  • ODataModel的默认操作模式或
    默认操作模式的名称必须是
    “客户端”
    ,或者如果适用,
    “自动”
  • 调用时,作为第二个参数传递的需要是
    “Control”



对于服务器端筛选,仅支持筛选类型
“应用程序”
。然后,服务器需要显式生成过滤后的树结构。

根据ODataTreeBinding via“navigation”属性,不推荐使用。然而,应该支持过滤。ODataModel的
defaultOperationMode
是什么?@boghyon操作模式设置为应用程序。我知道operationMode.Server不支持控制筛选器。您是指
客户端
(而不是应用程序)?啊,我指的是筛选器函数的参数。我没有为模型或绑定期间设置operationMode,因为默认operationMode是服务器,所以我的默认operationMode是服务器。感谢您的回复。我已经用OData服务的代码实现了您的示例,情况仍然是一样的。不过,感谢您指出getItems()函数。在调用filter()函数之前,getItems()函数的responseoE中只有四个根项。尽管如此,如果折叠一个节点,getItems()函数还将返回除根节点外的所有折叠节点。但即使它们在getItems()响应中,我也无法过滤它们。如果删除它们会发生什么?参数:{展开:'ChildGroupNodes',导航:{'GroupNodes':'ChildGroupNodes'}我猜您没有得到子节点?没错,是的。我刚刚遇到完全相同的问题。将ODataModel的操作模式从“服务器”更改为“客户端”部分解决了此问题。筛选工作正常,但仅适用于最初加载到本地模型中的项目。您是否找到正确筛选整个后端的解决方案?@jor使用服务器端操作模式,后端负责以树状结构响应筛选请求,但恐怕没有标准由于OData没有指定响应体,因此它应该是什么样子的解决方案。但是,有一个主题可能会对您有进一步的帮助:非常感谢您提供的链接!据我所知,在添加“的层次结构节点后代计数”时,我的所有问题都应该得到解决注释。@BoghyonHoffmann您是否尝试过搜索父节点,默认情况下,搜索父节点只显示父节点,不显示其子节点。搜索父节点时保留子节点的任何方法。