Цезий в Drupal: просмотр загрузки на странице в Drupal

ВАЖНОЕ ПРИМЕЧАНИЕ При создании объекта цезия в обычном проекте у него нет никаких свойств, которые имеют префикс с подчеркиваниями (_dataSourceCollection, _dataSourceDisplay и т.д.). Однако при создании экземпляра в Drupal в дополнение к обычным свойствам объекта (все префиксы с подчеркиванием) задаются около 40-45 свойств. Это происходит в Drupal 7 или 8, и хотя я не уверен, что это имеет отношение к проблеме, с которой я столкнулся, это было заметное несоответствие, и поэтому я думал, что он должен быть общим.

Я добавил библиотеку Cesium в проект Drupal, поместив файл в sites/all/libraries/цезий/Cesium.js вместе с папками Assets and Widgets, а затем также вызвав hook_library_info в пользовательский модуль

function cesium_library_info() {
  $libraries['cesium'] = array(
    'files' => array(
      'js' => 'Cesium.js',
    ),
    'path' => 'js',
    'library path' => libraries_get_path('cesium'),
    'version' => '1'
  );
  return $libraries;
}

Затем я использую hook_menu для возврата обратного вызова следующей страницы:

function cesium_page()  {
  drupal_add_js(libraries_get_path('cesium') . '/Cesium.js');
  drupal_add_js(drupal_get_path('module', 'cesium') . '/js/mCesium.js');
  drupal_add_css(libraries_get_path('cesium') . '/Widgets/widgets.css');

  $page = array();

  $page['ces-container'] = array(
    '#prefix' => '<div id="myApp-cesium">',
    '#suffix' => '</div>',
    '#markup' => '<h1>Welcome to Cesium!',
  );
  return $page;
}

mCesium.js содержит код, в котором Cesium вызывается из Drupal.behaviors, чтобы подключить средство просмотра к элементу # myApp-цезия.

Drupal.behaviors.cesium = {
  attach: function (context, settings) {

    var viewer = new Cesium.Viewer('myApp-cesium', {
        imageryProvider : new Cesium.createOpenStreetMapImageryProvider({
            url : 'http://thebestmaptiles.map.tile.com/',
        }),
        baseLayerPicker : false
    });
  }
}

Это успешно создает средство просмотра в соответствующем элементе внутри основного контейнера страницы Drupal. Однако зритель полностью лишен содержимого, и в консоли отображается следующая ошибка:

Cesium.js:169769 Uncaught TypeError: this._dataSourceAdded is not a function

Значение "this" не равно null или undefined, но, по-видимому, является структурой, предполагающей неполностью сформированный объект Viewer. В этом объекте отсутствуют все свойства, которые будут иметь префикс с подчеркиванием, например _dataSourceAdded.

Кто-нибудь может понять, почему это может быть?

Наконец, перед публикацией этого сообщения я увидел, что есть модуль Drupal для Cesium, который имеет что-то интересное в hook_libraries_info_alter, где кодовая база Cesium сохраняется как public://cesium_base_url.js.

См. строки 50-59 в cesium.module, найденные в https://www.drupal.org/project/cesium

 47 function cesium_libraries_info_alter(&$libraries) {                                                                             
 48   $library = libraries_detect('cesium');                                                                                        
 49                                                                                                                                 
 50   if ($library['installed'] == TRUE) {                                                                                          
 51     $data = "var CESIUM_BASE_URL = '" . url($library['library path'] . '/Build/Cesium/') . "';";                                
 52     $jsfile = file_unmanaged_save_data($data, 'public://cesium_base_url.js', FILE_EXISTS_REPLACE);                              
 53                                                                                                                                 
 54     $libraries['cesium']['files']['js'][$jsfile] = array(                                                                       
 55       'data' => $jsfile,                                                                                                        
 56       'weight' => 0,                                                                                                            
 57       'group' => JS_LIBRARY,                                                                                                    
 58     );                                                                                                                          
 59   }                                                                                                                             
 60 }            

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

ИЗМЕНИТЬ

Я также хотел бы упомянуть, что я воспроизвел ту же ситуацию с той же ошибкой как на Drupal 7, так и на Drupal 8.

Вот код, загруженный без Drupal.behaviors, который, опять же, создает ту же ситуацию с некомпетентно загруженным объектом Cesium.Viewer:

setTimeout(function() {

    var viewer = new Cesium.Viewer('myApp-cesium', {
        imageryProvider : new Cesium.createOpenStreetMapImageryProvider({
            url : 'http://thebestmaptiles.map.tile.com/',
        }),
        baseLayerPicker : false
    });
}, 5000);

ДРУГОЕ ОБНОВЛЕНИЕ:

Размещение javascript внутри обертки jQuery не дает никакой пользы.

Я также пытался увидеть, поможет ли добавление библиотек в функции hook_init(), но это не так.

ДРУГОЕ ОБНОВЛЕНИЕ:

Известные несоответствия - объект просмотра в приложении HelloWorld и Drupal

Переменные среды для наблюдений:

Я отправляю "this" в console.log внутри функции Viewer для Cesium.js, ПОСЛЕ того, что все частные свойства были установлены (свойства с префиксом _underscore) и непосредственно перед вызовом функции _dataSourceAdded в объекте Viewer (строка 169769 на моем измененном, unminified Cesium.js)

console.log(this);
var dataSourceLength = dataSourceCollection.length;
for (var i = 0; i < dataSourceLength; i++) {
    this._dataSourceAdded(dataSourceCollection, dataSourceCollection.get
   (i));          

Вот основные отличия:

Приложение HelloWorld - 41 свойство (в соответствии с console.log(Object.keys(this).length);)

  • Признан как объект "Просмотр"

  • Переключение на "ключ в объекте" найдено 61 свойство

  • 53 из них были частными

Приложение Drupal - 41 свойство (Object.keys(this).length))

  • Распознан как объект "Объект"

  • Переключение на "ключ в объекте" найдено 61 свойство

  • 0 из них были частными

Ответы

Ответ 1

Приведенный выше код имел эту строку для создания зрителя:

var viewer = Cesium.Viewer('myApp-cesium',

Не удалось найти ключевое слово new:

var viewer = new Cesium.Viewer('myApp-cesium',

Ключевое слово new необходимо для правильной конструирования нового экземпляра средства просмотра цезия. Подробнее о том, что именно делает new, см. этот ответ в переполнении стека.

Ответ 2

Прогресс в этом. Оказывается, каждый из каталогов Assets/Widgets/Workers должен находиться в библиотеках/цезие/Build/Cesium/

Теперь глобус появляется нормально и, кажется, работает (нужно проверить, есть ли ограничения). Однако ошибка "this._dataSourceAdded не является функцией" все еще остается, хотя она, похоже, не вызывает никаких проблем, насколько я могу еще сказать.

Я буду обновлять после тестирования.