2015-01-15 2 views
0

Я расширяю sap.ui.unified.Calendar с настраиваемым элементом управления, переопределяя функцию renderDays(), чтобы поместить дополнительный тег span в каждый день div.Выполнение индивидуального контроля дважды

Консоль указывает, что массив часов не определен. Он выдает ошибку, найденную ниже, но продолжает работать после этого. Эта ошибка не позволяет перемещать стрелки заголовка между месяцами в календаре. Является ли этот рендеринг дважды? Почему часы [] не определены сначала, но нормально?

Если я поместил весь код в один файл JSBin, это не ошибка. JSBin

В верхней части кода для пользовательского элемента управления:

sap.ui.unified.Calendar.extend("control.TimeCalendar", { 
    metadata : { 
     properties : { 
      "hoursData" : "string[]" 
     } 
    }, 

    renderer: { 
    renderDays: function(oRm, oCal, oDate){ 
     var hours = oCal.getHoursData(); 

Консоль вывода:

Cannot read property 'length' of undefined 

Выписка из TimeCalender.js таможенного контроля. Это внутри цикла do ... while, который помещает каждый день в календарь. Если функция помещает дату, я также включаю тег span с номером, полученным из массива «часы».

oRm.write("<span class=\"sapUiCalDayNum\">"); 

if ((hours.length>i) && (hours[i].day == oDay.getUTCDate())) { 
    oRm.write("<span class=\"hours\">"); 
    oRm.write(hours[i].hours); 
    oRm.write("</span>"); 
    if(i <= hours.length) { i++; } 
} 

oRm.write(oDay.getUTCDate()); 
oRm.write("</span>"); 

ответ

0

Принимая догадку, я бы сказал, что в вашем без jsbin сценарии вы используете привязки данных, и данные, полученные либо asynchonously от заднего конца или он устанавливается после первого рендеринга?

В этом случае значение hoursdata установлено на неопределенное, что вызывает ошибку.

Если определить свойство как это:

properties : { 
    "hoursData" : { type: "string[]", defaultValue: [] } 
} 

... Таким образом, вы убедитесь, что всегда есть массив, который имеет свойство длины.

+0

Спасибо за помощь. Я считаю, что проблема заключалась в том, что она загружалась асинхронно, как вы сказали. Когда я изменил модель в контроллере, чтобы читать из переменной, определенной в том же файле, вместо указания на URL-адрес json-файла, он работал. Поэтому я изменил контроллер на использование loadData и установил флаг async в false, и это устранило проблему. Позднее я перешел на службу OData, у которой также была асинхронная к false, и она тоже работала. – pyro

+1

Синхронная загрузка - это неправильный способ сделать это практически в каждом случае - он блокирует поток пользовательского интерфейса и часто приводит к плохому пользователю. Вы должны использовать значение по умолчанию и подумать о некоторой логике внутри вашего рендеринга - например, прервать, когда данные не установлены, поэтому вы можете использовать асинхронную загрузку, когда это необходимо. – sirion

+0

Я понимаю, что это плохая идея, чтобы загрузить его синхронно. Однако я все еще получаю неопределенную ошибку при изменении моего вызова OData для асинхронности даже с предложением defaultValue: []. Я использовал typeof для определения типа getHoursData(), и это объект, а не неопределенный, которого я не ожидал. – pyro

Смежные вопросы