Drupal中的Cesium:在Drupal

时间:2016-09-10 17:50:29

标签: drupal drupal-7 drupal-8 cesium

重要提示 在普通项目中实例化Cesium对象时,它没有任何以下划线为前缀的属性(_dataSourceCollection,_dataSourceDisplay等)。但是,在Drupal中实例化时,除了常用属性外,还在对象上设置了大约40-45个属性(所有属性都带有下划线)。这发生在Drupal 7或8中,虽然我不确定这是否与我遇到的问题有关,但这是一个明显的差异,因此我认为它应该被分享。

我已将Cesium库添加到Drupal项目中,方法是将文件放在sites / all / libraries / cesium / Cesium.js中,同时放置Assets和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包含从Drupal.behaviors中调用Cesium的代码,用于将查看器附加到我的#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

&#34;这个&#34;的价值不是null或未定义,但似乎是建议不完整形成的Viewer对象的结构。此对象缺少所有以下划线为前缀的属性,例如_dataSourceAdded。

有没有人知道为什么会这样?

最后,就在发布之前,我看到有一个针对Cesium的Drupal模块,它在hook_libraries_info_alter中发生了一些有趣的事情,其中​​Cesium代码库被保存为public://cesium_base_url.js。

https://www.drupal.org/project/cesium

中的cesium.module第50-59行
 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 App与Drupal中的查看器对象

观测环境变量:

我正在发送&#34;这个&#34;在Cesium.js的Viewer函数内部的console.log,在设置了所有私有属性之后(以_underscore为前缀的属性),并且在调用Viewer对象上的_dataSourceAdded函数之前(我修改的,未经过破坏的Cesium上的第169769行)的.js)

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

以下是主要区别:

HelloWorld App - 41个属性(根据console.log(Object.keys(this).length);)

  • 被认可为&#34;观众&#34;对象

  • 循环使用&#34;键入obj&#34;找到61个房源

  • 其中53个是私人的

Drupal App - 41个属性(Object.keys(this).length))

  • 被认可为&#34;对象&#34;对象

  • 循环使用&#34;键入obj&#34;找到61个房源

  • 其中0个是私人的

2 个答案:

答案 0 :(得分:4)

上面的代码最初有这一行来创建一个查看器:

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

缺少new关键字:

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

正确构建Cesium查看器的新实例需要new关键字。有关new完全执行的操作的详细信息,请参阅this answer on Stack Overflow

答案 1 :(得分:3)

在此方面取得了一些进展。事实证明,每个Assets / Widgets / Workers目录都必须位于libraries / cesium / Build / Cesium /

现在,地球仪正常显示并且似乎正在运行(需要测试以确定是否存在限制)。然而,“this._dataSourceAdded不是函数”错误仍然存​​在,尽管它似乎并没有引起任何问题。

经过更多测试后我会更新。