Цезий в 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);)
Приложение Drupal
- 41 свойство (Object.keys(this).length))
Ответы
Ответ 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 не является функцией" все еще остается, хотя она, похоже, не вызывает никаких проблем, насколько я могу еще сказать.
Я буду обновлять после тестирования.