简体   繁体   English

使用JQuery在SAP UI5模板处理程序中访问样式的行

[英]Access row for styling in SAP UI5 template handler using JQuery

I'm trying to get UI5 to change the row backgound based on the value of a field. 我正在尝试让UI5根据字段的值更改行背景。 This works after the initial load has been done and you scroll, but it doesn't work on the initial load. 在完成初始加载并滚动后,此方法有效,但是在初始加载中不起作用。

This isn't working because the cell hasn't been added to its parent container as far as I can tell this.$().closest('tr') returns nothing. 就我所知, this.$().closest('tr')单元格没有被添加到其父容器中this.$().closest('tr')返回任何内容。 Upon scrolling the cell has been added to its parent, and then everything woks just fine. 滚动时,该单元格已添加到其父级,然后一切正常。

<!DOCTYPE html>  
<html><head>  
    <meta http-equiv='X-UA-Compatible' content='IE=edge' />  
    <title>Bindign Rows</title>  

    <script id='sap-ui-bootstrap' 
        src='https://openui5.hana.ondemand.com/resources/sap-ui-core.js'  
        data-sap-ui-theme='sap_bluecrystal'  
        data-sap-ui-libs='sap.ui.commons,sap.ui.table'></script>   

    <script>  
       var data = [
           {sex: 'm', fname: 'XXX' , lname : 'YYYYY'},
           {sex: 'm', fname: 'XXX' , lname : 'YYYYY'},
           {sex: 'f', fname: 'XXX', lname : 'YYYYY'},
           {sex: 'f', fname: 'XXX', lname : 'YYYYY'} ,
           {sex: 'm', fname: 'XXX', lname : 'YYYYY'},
           {sex: 'f', fname: 'XXX', lname : 'YYYYY'}
       ];

       var oTable = new sap.ui.table.Table({visibleRowCount: 3});
       var oModel = new sap.ui.model.json.JSONModel();
       oModel.setData({modelData: data});
       oTable.setModel(oModel);

       var template1 = new sap.ui.commons.TextField().bindProperty("value", "sex", 
           function(sex){
              if(sex == "m" ){
                  //  !! the below parent can't be found.
                  this.$().closest("tr").css("background-color", "red");            
              }  else  if(sex == "f" )
              {  
                  this.$().closest("tr").css("background-color", "inherit");
              }
              return sex ;
            }
        );

        oTable.addColumn(new sap.ui.table.Column({ label: "Sex",
                                             template:  template1}));

    oTable.placeAt('content');  
    oTable.bindRows("/modelData");
</script>

</head>
<body class='sapUiBody'>
    <div id='content'></div>
</body>
</html>

What you'll see is that upon initial load all cells are grey. 您会看到,在初始加载时,所有单元格都是灰色的。

When you scroll all cells with sex:M will get a red background. 滚动所有带有sex:M的单元格时,背景将变为红色。 We'd love it if the red background would populate right from the first load. 如果红色背景从第一次加载就开始填充,我们将非常喜欢。

在此处输入图片说明

JsBin link JsBin链接


Things we tried: 我们尝试过的事情:

  • Supplying the template to the call to .bindRows('/data', template1) , it seems that the type of template to supply to this call is a different one, but hardly documented on the SAP website. 将模板提供给.bindRows('/data', template1)调用,似乎可以提供给此调用的模板类型是不同的模板,但是几乎没有在SAP网站上进行记录。
  • Calling bindRows twice. 两次调用bindRows
  • WORKAROUND: >>> doing the styling on a timer, works but is ugly and not stable enough. 解决方法:>>> 在计时器上进行样式设置是可行的,但是很丑陋并且不够稳定。
  • I can't find a onParentChanged handler, onLoad or similar event that triggers after the data has been bound and I can't find an event akin to thd onDataBinding vs onRowCreated that I'm used to from my .NET background. 我找不到在绑定数据后触发的onParentChanged处理程序, onLoad或类似事件,也找不到类似于从.NET背景使用过的类似于onDataBinding vs onRowCreated的事件。
  • Just changing the style of the textbox itself works as is to be expected. 只需更改文本框本身的样式即可。

Better Solution 更好的解决方案

Combined addDelegate with the scroll handler on the vertical scrollbar, not ideal because they are both undocumented features 将addDelegate与垂直滚动条上的滚动处理程序结合使用,并不理想,因为它们都是未记录的功能

function updateRows(oEvent) {
    if (oEvent.type !== 'AfterRendering'){
      this.onvscroll(oEvent);
    }
    var rows = this.getVisibleRowCount();   //number of rows on tab
    var rowStart = this.getFirstVisibleRow();
    var ctx;
    for (var i=0; i<rows; i++){
       ctx = this.getContextByIndex(rowStart + i); //content
       this.getRows()[i].$().toggleClass("male",ctx?ctx.getObject().sex === 'm':false);
    }
};

oTable.addDelegate({ onAfterRendering : $.proxy(this.updateRows, oTable)});
oTable._oVSb.attachScroll(this.updateRows,oTable); 

see updated jsBin example 查看更新的jsBin示例

WORKAROUND 替代方法

Introducing a timer seems to work around the issue. 引入计时器似乎可以解决此问题。 I find it a very ugly solution and I'd prefer a better one, at least this seems to get us unstuck. 我发现这是一个非常丑陋的解决方案,我希望有一个更好的解决方案,至少这似乎使我们感到困惑。 Very much open to a better solution: 对更好的解决方案非常开放:

var template1 = new sap.ui.commons.TextField().bindProperty("value", "sex", 
  function(sex){
    var changeRow =  function(cell)
    {
      var row =  cell.$().closest("tr");
      if (row != undefined)
      {
        if(sex == "m" ){
          row.css("background-color", "red");            
        } 
        else
        {  
          row.css("background-color", "inherit");
        }
      }  
    };

    var row =  this.$().closest("tr");
    if (row.length != 0)
    {
      changeRow(this);
    }   
    else
    {
      // might need to increase the timeout. in the demo 150ms seems to be enough.
      window.setTimeout(changeRow, 150, this);
    }
    return sex ;
  }
);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM