Sapui5 bindElement何时调用真正的服务?

Sapui5 bindElement何时调用真正的服务?,sapui5,Sapui5,Main.view.xml: <ObjectHeader id="objectHeader" title="{name}" intro="{id}"> <headerContainer> <IconTabBar id="tabBar" items="{ path: 'assigned', parameters

Main.view.xml:

<ObjectHeader
    id="objectHeader"
    title="{name}"
    intro="{id}">
    <headerContainer>
        <IconTabBar
            id="tabBar"
            items="{
                path: 'assigned',
                parameters: {expand: 'b, c'} 
            }"
            select="onTabBarSelect">
        </IconTabBar>       
    </headerContainer>
</ObjectHeader>
我发现了一个奇怪的行为:当我更改主列表选择时,有时网络会显示“/ASet/assigned”调用,但有时不会有调用,这会导致
requestCompleted
未触发

根据:

如果使用相同的路径调用bindElement两次,第二次实际上不会触发新调用以获取新数据,因为路径没有更改

但我相信这是另一条路。有没有办法触发这个电话


顺便说一句


change
可以在每次单击主列表时触发,但从未调用
datarequest
dataReceived

如果您的ODataModel已经在
sPath
下加载了数据(签入
myODataModel.oData
),则不会再次加载该数据。因此,
datarequest
/
dataReceived
将不会触发


但是无论数据是否存在,只要路径发生变化,
change
就会触发。

我通过将
bindElement
替换为
change
&
oModel.read

onMasterSelectionChange : function (sPath) {
    var oSource = oEvent.getParameter("listItem") || oEvent.getSource(),
    // sPath = "/ASet('d')"
    sPath = oSource.getBindingContext().getPath(),
    oObjectHeader = this.byId("objectHeader");

    oObjectHeader.bindElement({
        path : sPath,
        events: {
            change : this._onBindingChange.bind(this, sPath)
        }
    })
},

_onBindingChange : function(sPath) {
    this._oModel.read(sPath + "/assigned", {
        urlParameters: {
            "$expand": "b, c"
        },
        success: function(oData) {
            var aAssigmentSet = oData.results,
            oViewModel = this.getModel("viewModel"),
            oTabBar =  this.byId("hazardTabBar");

            oViewModel.setProperty("/aAssigmentSet", aAssigmentSet);
            oTabBar.bindAggregation("items",
                "viewModel>/aAssigmentSet",
                new sap.m.IconTabFilter({
                    key: "{viewModel>id}",
                    tooltip : "{viewModel>id}",
                    text : {
                        parts: [{path: "viewModel>b/name"},
                        {path: "viewModel>c/type"}],
                        formatter : function(name, type) {
                            var sType = type.split(".");
                            return name + " (" + sType[sType.length - 1] + ")"; 
                        }
                    }
                })
            );

            if (oTabBar.getItems().length > 0) {
                var sSelectedTabKey;
                    sSelectedTabKey = oTabBar.getItems()[0].getKey();
                    oTabBar.fireSelect({selectedKey: sSelectedTabKey});
            }
        }.bind(this),
        error: this.errorCallback.bind(this)
    });
},

onTabBarSelect : function(oEvent) {
    var sRiskAssignmentPath = "/AssignmentSet('" + oEvent.getParameter("selectedKey") + "')";

    this._oModel.read(AssignmentSet + "/assignedAssignedControls", {
        ...
    }); 
}

我知道这是一篇老文章,但实际上可以通过刷新
change
事件中的绑定来触发对
bindElement
的网络调用

this.getView().bindElement({
    path: "model>/" + sContextPath,
    events: {
        change: function (oEvent) {
            // Get the context binding object
            var oContextBinding = oEvent.getSource();

            // Refresh the binding.
            // This triggers a network call.
            oContextBinding.refresh(false);
        }.bind(this)
    }
});

刷新绑定将触发网络调用。另外,将
refresh
bForceUpdate
标志设置为
false
,这样它只会在数据发生更改时更新UI,如中所述。

我认为实现这一点的最佳方法是使用Odata模型中的invalidate方法

这将使所有缓存的条目无效,并强制对绑定进行新的读取:


ODataContextBinding.prototype.设置断点。
并查看那里发生了什么(特别是在
breLoadRequired
)您能告诉我们您的应用程序是如何构造的以及绑定是如何完成的(除了ObjectHeader之外)?您是否使用扩展到“详细信息”将集合绑定到主集合?在这种情况下,以后不发送请求是有意义的,因为无论您选择什么,数据都已被缓存。对不起,如何获取
ODataContextBinding
?是的,它是带有
展开的主细节。我的目标是加载第一个主列表项,并在页面打开时激活第一个图标选项卡栏。是的,它被缓存。但在
dataReived
之后,我想触发一些逻辑,我该怎么办?奇怪的是,我设置了一个日志a
datarequest/dataReceived
,它们从未触发。你的主机可能已经加载了所有数据。一旦您选择了一个条目(
onMasterSelectionChange
),您就可以将详细视图绑定到其中一个已加载的条目上。因此,它永远不会触发
datarequest
/
dataReceived
。但是如果我使用
var-otabar=this.byId(“TabBar”);oFirstListItem=oTabBar.getItems()[0],
更改中,数据尚未绑定…可能是在父级更改事件之后发生的递归绑定更新:/通常SAPUI5事件的时间和特定性非常糟糕。。。
onMasterSelectionChange : function (sPath) {
    var oSource = oEvent.getParameter("listItem") || oEvent.getSource(),
    // sPath = "/ASet('d')"
    sPath = oSource.getBindingContext().getPath(),
    oObjectHeader = this.byId("objectHeader");

    oObjectHeader.bindElement({
        path : sPath,
        events: {
            change : this._onBindingChange.bind(this, sPath)
        }
    })
},

_onBindingChange : function(sPath) {
    this._oModel.read(sPath + "/assigned", {
        urlParameters: {
            "$expand": "b, c"
        },
        success: function(oData) {
            var aAssigmentSet = oData.results,
            oViewModel = this.getModel("viewModel"),
            oTabBar =  this.byId("hazardTabBar");

            oViewModel.setProperty("/aAssigmentSet", aAssigmentSet);
            oTabBar.bindAggregation("items",
                "viewModel>/aAssigmentSet",
                new sap.m.IconTabFilter({
                    key: "{viewModel>id}",
                    tooltip : "{viewModel>id}",
                    text : {
                        parts: [{path: "viewModel>b/name"},
                        {path: "viewModel>c/type"}],
                        formatter : function(name, type) {
                            var sType = type.split(".");
                            return name + " (" + sType[sType.length - 1] + ")"; 
                        }
                    }
                })
            );

            if (oTabBar.getItems().length > 0) {
                var sSelectedTabKey;
                    sSelectedTabKey = oTabBar.getItems()[0].getKey();
                    oTabBar.fireSelect({selectedKey: sSelectedTabKey});
            }
        }.bind(this),
        error: this.errorCallback.bind(this)
    });
},

onTabBarSelect : function(oEvent) {
    var sRiskAssignmentPath = "/AssignmentSet('" + oEvent.getParameter("selectedKey") + "')";

    this._oModel.read(AssignmentSet + "/assignedAssignedControls", {
        ...
    }); 
}
this.getView().bindElement({
    path: "model>/" + sContextPath,
    events: {
        change: function (oEvent) {
            // Get the context binding object
            var oContextBinding = oEvent.getSource();

            // Refresh the binding.
            // This triggers a network call.
            oContextBinding.refresh(false);
        }.bind(this)
    }
});