在 React/Esri 应用程序中通过 JSON 配置进行配置时,小部件不添加层

问题描述 投票:0回答:1

我正在使用 ArcGIS Experience Builder。

我正在开发一个 React 组件,用于切换 Esri 地图中地图图层的可见性。当我对层配置进行硬编码时,我的小部件工作得很好,但是当我从 config.json 文件加载配置时,我的小部件无法添加层。

工作代码示例:

import { React, AllWidgetProps } from 'jimu-core';
import { JimuMapViewComponent, JimuMapView } from 'jimu-arcgis';
import FeatureLayer from 'esri/layers/FeatureLayer';
import { IMConfig } from '../config';
const { useState, useEffect } = React;

const layersConfig = [
  {
    name: "Layer 1",
    url: "https://example.com/arcgis/rest/services/Layer1/MapServer/0",
  },
  {
    name: "Layer 2",
    url: "https://example.com/arcgis/rest/services/Layer2/MapServer/0",
  }
];

const Widget = (props: AllWidgetProps<IMConfig>) => {
  const [jimuMapView, setJimuMapView] = useState<JimuMapView>(null);
  const [layers, setLayers] = useState([]);

  useEffect(() => {
    if (props.config && props.config.layers) { //not necessary in this case
      const initialLayers = layersConfig.map(layerConfig => ({
        ...layerConfig,
        layer: new FeatureLayer({
          url: layerConfig.url,
          title: layerConfig.name,
          visible: false
        })
      }));
      console.log('Initial layers:', initialLayers); 
      setLayers([...initialLayers]);
    }
  }, [config.props]); //also not necessary in the working sample

  const activeViewChangeHandler = (jmv: JimuMapView) => {
    if(jmv) {
      setJimuMapView(jmv);
      layers.forEach(({ layer }) => jmv.view.map.add(layer));
    }
  };

  const toggleLayerVisibility = (index) => {
    const newLayers = layers.map((layer, idx) => {
      if (idx === index) {
        layer.layer.visible = !layer.layer.visible;
      }
      return layer;
    });
    setLayers(newLayers);
  };

  return (
    <div>
      {props.useMapWidgetIds && props.useMapWidgetIds.length === 1 && (
        <JimuMapViewComponent props.useMapWidgetId={props.useMapWidgetIds[0]} onActiveViewChange={activeViewChangeHandler} />
      )}
      <div>
        {layers.map((layer, index) => (
          <label key={index}>
            <input
              type="checkbox"
              checked={layer.layer.visible}
              onChange={() => toggleLayerVisibility(index)}
            />
            {layer.name}
          </label>
        ))}
      </div>
    </div>
  );
};

export default Widget;

非工作代码(使用 config.json):

// Similar to the above, but `layersConfig` is replaced with `props.config.layers`
useEffect(() => {
    if (props.config && props.config.layers) {
      const initialLayers = props.config.layers.map(layerConfig => ({ //<--- This changed!
        ...layerConfig,
        layer: new FeatureLayer({
          url: layerConfig.url,
          title: layerConfig.name,
          visible: false
        })
      }));
      console.log('Initial layers:', initialLayers); 
      setLayers([...initialLayers]);
    }
  }, [props.config]);

config.json:

{
  "layers": [
    {
      "name": "Layer 1",
      "url": "hidden",
    },
    {
      "name": "Layer 2",
      "url": "hidden"
    }
  ]
}

配置.ts:

import { ImmutableObject } from 'seamless-immutable';

export interface LayerConfig {
  name: string;
  url: string;
}

export interface Config {
  layers: LayerConfig[];
}

export type IMConfig = ImmutableObject<Config>;

错误信息:

[esri.WebMap] #add() The item being added is not a Layer or a Promise that resolves to a Layer.

此错误发生在我尝试向地图添加图层的行:

layers.forEach(({ layer }) => jmv.view.map.add(layer));

额外:

这是工作示例的初始层:

工作样本的初始层

对于没有工作的人:

非工作样本的初始层

  1. 检查配置文件中的 URL,确保它们正确且可访问。
  2. 向组件中的各个点添加日志,以确保数据正在加载并且状态更改按预期发生。
  3. 确保组件在状态更改时正确重新渲染。

请帮忙,在过去的 10 个小时里我一直在尝试通过不同的方式来解决这个问题...

编辑:

我将非常感谢任何形式的帮助或建议,如果需要,我可以提供更多信息。

reactjs widget arcgis arcgis-js-api arcgis-server
1个回答
0
投票

自从我将它类型转换为 ImmutableObject 以来,它添加了一堆其他属性来掩盖它,我认为它没有被识别为一个层,所以我再次解析它:

useEffect(() => {
    let layersConfig = [];
    if (props.config && props.config.layers) {
      // Parse the JSON string to JavaScript object
      layersConfig = JSON.parse(JSON.stringify(props.config.layers));

      const initialLayers = layersConfig.map(layerConfig => {
        return {
          ...layerConfig,
          layer: new FeatureLayer({
            url: layerConfig.url,
            title: layerConfig.name,
            visible: false
          })
        };
      });
      setLayers([...initialLayers]);
    }
  }, [props.config]);
© www.soinside.com 2019 - 2024. All rights reserved.