typescript - 为什么 SceneView 渲染不正确

标签 typescript arcgis-js-api

我正在快速了解 ArcGIS JS Api 版本 4.x,并认为这是对 Typescript 和 Widget 架构的一个很好的练习,用于实现一个小部件,该小部件在当前的顶部显示一个 SceneView map View

/// <amd-dependency path="esri/core/tsSupport/declareExtendsHelper" name="__extends" />
/// <amd-dependency path="esri/core/tsSupport/decorateHelper" name="__decorate" />

import EsriMap from 'esri/Map';
import SceneView = require("esri/views/SceneView");

import { aliasOf, declared, property, subclass } from "esri/core/accessorSupport/decorators";

// building Widgets
import Widget = require("esri/widgets/Widget");
import { accessibleHandler, renderable, cssTransition, tsx } from "esri/widgets/support/widget";


// CSS class lookup object
const CSS = {
    base: "app-sceneView",
    iconClass: "esri-icon-layer-list"
};

@subclass("Widgets.SceneViewWidget")
export default class SceneViewWidget extends declared(Widget) {

    constructor(params?: any) {
        super();
    }

    //icon class for the expand widget(!)
    @property()
    iconClass = CSS.iconClass;

    map: EsriMap = null;

    _bindView() {
        const view = new SceneView({
            map: this.map,
            container: "sceneView-container"
        });
    }

    render() {
        return <div id="sceneView-container" class={CSS.base} afterCreate={this._bindView}></div>
    }
}

小部件的容器在所需的位置很好地呈现,并且诸如缩放按钮之类的控件也在那里,但是当像这样调用时, map 没有呈现:

const map = new EsriMap({
    basemap: "streets",
    ground: "hybrid"
});
const mapView = new MapView({
    map: map,
    container: "mapView",
    center: [-118.244, 34.052],
    zoom: 12,
    ui: {
        components: ["zoom", "compass"]
    }
});

const sceneView = new SceneViewWidget({
    map: map
});

mapView.ui.add(sceneView, "top-right");

enter image description here

正如你所看到的。 div 的边界在那里,控件被渲染并且属性也在那里。仅缺少 SceneView 本身。这是为什么?

最佳答案

原因 SceneView 上面的 TypeScript 代码中没有渲染的是 this.map_bindView()为空,因为 this是函数作用域而不是对象作用域。

_bindView() {
  new SceneView({
    map: this.map,
    container: "sceneView-container"
  });
}

可以通过传递正确范围的 _bindView() 来解决这个问题函数位于 render() :

render() {
  return <div afterCreate={this._bindView.bind(this)} id="sceneView-container" class={CSS.base}></div>;
}

render() {
  return <div afterCreate={() => this._bindView()} id="sceneView-container" class={CSS.base}></div>;
}

请参阅以下 CodePen 的工作演示(纯 JavaScript): https://codepen.io/arnofiva/pen/1a801eca6a01ca9bf7625f89f906b6e7


此外,我还建议更改上面代码中的以下内容:

  • 包裹 SceneView容器sceneView-container在另外的<div>中避免 Widget 和 SceneView 共享相同的元素:
<div><div id="sceneView-container" class={CSS.base} afterCreate={this._bindView.bind(this)}></div></div>
const map = new EsriMap({
  basemap: "streets",
  ground: "world-elevation"
});
  • 提供单独的Map实例到 MapViewSceneView ,避免两种观点相互干扰。只需使用 new EsriMap(...) 创建一个新的.

关于typescript - 为什么 SceneView 渲染不正确,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/58814934/

相关文章:

javascript - 在没有 map 的情况下使用 JavaScript 为 ArcGIS popupInfo 生成 html

security - ArcGIS JavaScript API 中的参数化查询

javascript - 添加带有 JS 示例代码的 shapefile

angular - 无法绑定(bind)到 'countUp',因为它不是 'h1' 的已知属性。 countup.js-angular2

twitter-bootstrap - 我在 "ngx-bootstrap"和 "@ng-bootstrap/ng-bootstrap"之间感到困惑

typescript - 无法解决以 ElementArrayFinder 作为参数的 promise

javascript - 将 JavaScript AJAX Web API 查询转换为 PHP CURL

javascript - 如何将遗留的 Dojo Toolkit 代码转换为 AMD?

TypeScript 条件返回类型 : works for one condition but not for two

TypeScript 2.8.3 类型必须具有返回迭代器的 Symbol.iterator 方法