我通过将文件放置在sites/all/libraries/cesium/Cesium.js中并附带资源和小部件文件夹来将Cesium库添加到Drupal项目中,然后在自定义模块中调用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 包含了从Drupal.behaviors中调用Cesium以将Viewer附加到我的#myApp-cesium元素的代码。
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。请参阅cesium.module中的第50-59行,该文件位于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中的Viewer对象
用于观察的环境变量:
我将“this”发送到Cesium.js中Viewer函数内,在设置完所有私有属性(前缀为_underscore的属性)之后,并在调用查看器对象上的_dataSourceAdded函数之前(在我修改的未压缩的Cesium.js上的第169769行)。
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));
被识别为“查看器”对象;
循环“key in obj”发现61个属性;
其中53个是私有的。
Drupal应用程序 - 41个属性(Object.keys(this).length);
被识别为“对象”对象;
循环“key in obj”发现61个属性;
其中0个是私有的。
var viewer = Cesium.Viewer...
,这里缺少了一个new
关键字。应该改为var viewer = new Cesium.Viewer...
。 - emackey