如何推迟触发格式化程序

How to postpone triggering formatter

我的一个表没有加载数据,并针对未定义的 OData 模型之一抛出一些错误。

<script id="sap-ui-bootstrap"
  src="/resources/sap-ui-core.js"
  data-sap-ui-libs="sap.m, sap.uxap, sap.ui.table"
  data-sap-ui-theme="sap_bluecrystal"
  data-sap-ui-compatVersion="edge"
  data-sap-ui-preload="async"
  data-sap-ui-resourceroots='{"com.ABC": ""}'
  data-sap-ui-xx-bindingSyntax="complex"
></script>

Controller.js

_initializeData: function() {
  var parts = {};
  parts.PartsByKey = "SP";
  parts.PriceColumn = false;
  parts.SubTotalColumn = false;
  this.orderMaterialsModel = new JSONModel(Parts);
  this.getView().setModel(this.orderMaterialsModel, "orderParts"); //Line number 6
  this.orderMaterialsModel.setProperty("/OrdersTotal", 0);
  /* works fine till here. But moment above statement is executed,
  the execution goes to the below formatter. The model which is 
  initialized in the next line is never executed, and then the
  formatter throws error - model undefined */
  this.salesOrderModel = this.getOwnerComponent().getModel("salesOrderModel");
  this._validationChecks(this.salesOrderModel.getData());
  this.getView().getModel("salesOrderModel").refresh(false);
  //...
},

// Formatter function for the table rows
formatQty: function(QOH, qty) {
  var oType = this.salesOrderModel.oData.type;
  // error here as this.salesOrderModel does not exists..
},

设置/OrdersTotal值时,异步进行:

this.orderMaterialsModel.setProperty("/OrdersTotal", 0, /*context*/null, /*async*/true );

说明

在视图定义的某处,您必须将 /OrdersTotalformatter: '.formatQty' 绑定。在末尾调用 setProperty 而没有 true 会首先触发所有依赖的侦听器(包括格式化程序), 然后 其余代码继续。

同步执行:

  1. _initializeData:

    // ...
    this.orderMaterialsModel.setProperty("/OrdersTotal", 0);
    
  2. formatQty中:

    var oType = this.salesOrderModel.oData.type; // Error! this.salesOrderModel is undefined
    // ...
    
  3. 继续_initializeData

    this.salesOrderModel = this.getOwnerComponent().getModel("salesOrderModel");
    // ...
    

true 作为 setPropertyAPI 中的第四个参数传递将确保 _initializeData 中的剩余代码行首先处理,所有依赖的监听器将作为最后一个任务放入调用堆栈中。

异步执行:

  1. _initializeData:

    this.orderMaterialsModel.setProperty("/OrdersTotal", 0, null, true);
    this.salesOrderModel = this.getOwnerComponent().getModel("salesOrderModel");
    //...
    
  2. formatQty中:

    var oType = this.salesOrderModel.oData.type;
    // ...
    

另一个问题是侦听器(例如格式化程序)也会在刚设置模型时被触发。

您可以通过在调用堆栈末尾设置模型来推迟触发,就像异步 setProperty 的情况一样,通过使用 requestAnimationFrame

// ...
window.requestAnimationFrame(function() {
  this.getView().setModel(this.orderMaterialsModel, "orderParts");
  // triggers the formatter
}.bind(this));
// ...