Строка доступа для стиля в обработчике шаблонов SAP UI5 с использованием JQuery

Я пытаюсь заставить UI5 изменить фон строки в зависимости от значения поля. Это работает после начальной загрузки и прокрутки, но не работает при начальной загрузке.

Это не работает, потому что ячейка не была добавлена ​​в родительский контейнер, насколько я могу судить, this.$().closest('tr') ничего не возвращает. При прокрутке ячейка была добавлена ​​к ее родителю, и тогда все работает нормально.

<!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>

Вы увидите, что при начальной загрузке все ячейки серые.

Когда вы прокрутите все ячейки с полем: М, вы получите красный фон. Нам бы понравилось, если бы красный фон заполнялся сразу после первой загрузки.

введите здесь описание изображения

ссылка JsBin


Что мы пробовали:

  • Предоставляя шаблон для вызова .bindRows('/data', template1), кажется, что тип шаблона для этого вызова отличается, но вряд ли задокументирован на веб-сайте SAP.
  • Дважды звонил bindRows.
  • ВРЕМЕННОЕ РЕШЕНИЕ: >>> стилизовать по таймеру, работает, но некрасиво и недостаточно стабильно.
  • Я не могу найти обработчик onParentChanged, onLoad или подобное событие, которое срабатывает после привязки данных, и я не могу найти событие, похожее на thd onDataBinding vs onRowCreated, к которому я привык из своего опыта работы с .NET.
  • Просто изменение стиля самого текстового поля работает так, как и следовало ожидать.

person jessehouwing    schedule 15.05.2014    source источник
comment
Поможет ли этот связанный вопрос? stackoverflow.com/questions/22704644/   -  person Qualiture    schedule 16.05.2014
comment
Да вроде связано. Дело в том, что onAfterRendering работает для первой таблицы, которую мы рисуем, но страница извлекает новые данные с помощью вызова Ajax, а раскраска для второй таблицы завершается неудачно... Попробуем собрать воедино вторую работу, которая показывает такое поведение.   -  person jessehouwing    schedule 17.05.2014


Ответы (2)


Лучшее решение

Комбинация 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); 

см. обновленный пример jsBin

person Jasper_07    schedule 16.05.2014
comment
Событие Scroll делает правильную окраску, но ломает полосу прокрутки при использовании колеса прокрутки. Это также нарушает такие вещи, как перетаскивание индикатора прокрутки в верхнюю часть экрана (он не показывает каждый раз самый верхний элемент в таблице). Отключение события прокрутки исправляет это. - person jessehouwing; 19.05.2014
comment
был существующий обработчик прокрутки, который был перезаписан, добавил его обратно, см. выше, и jsBin - person Jasper_07; 19.05.2014
comment
Ужасно, хотя это выглядит, это, кажется, делает работу :). - person jessehouwing; 19.05.2014
comment
Мы по-прежнему комбинировали его с решением по таймеру для лучшей общей стабильности... Я думал, что этот Javascript-фреймворк будет крутым и простым... - person jessehouwing; 19.05.2014
comment
Согласен, и определенно то, что должно быть возможно в более чистом готовом решении в будущей версии. Но сейчас я тоже приму это решение как текущий путь вперед, спасибо, что изучили это! - person Qualiture; 20.05.2014

ВРЕМЕННОЕ РЕШЕНИЕ

Введение таймера, кажется, решает проблему. Я нахожу это очень уродливым решением, и я бы предпочел лучшее, по крайней мере, это, кажется, выводит нас из тупика. Очень открыт для лучшего решения:

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 ;
  }
);
person jessehouwing    schedule 15.05.2014
comment
Пока что это в сочетании с oTable.addDelegate({ onAfterRendering : $.proxy(this.updateRows, oTable)}); кажется наиболее стабильным решением... - person jessehouwing; 19.05.2014