如何检测到应该更新先前对象的属性?

时间:2018-12-12 12:57:23

标签: javascript reactjs mapbox mapbox-gl-js

首先,感谢您阅读我的问题,并尝试帮助我并为我的英语道歉。

我正在尝试使用React在Redux上创建一种方法,以更改图层的可见性。

我的问题是更改可见性是完美的,但是当所有图层都不可见时,尝试将其更改为可见,则除最后一个更改之外,未定义其before属性。

我将用一个例子更好地解释我。

mapLayers是一个包含3层的数组:

  
      
  • [2]第3层
  •   
  • 1第2层
  •   
  • [0]第1层
  •   

情况1:

如果我隐藏Layer1,则他的before属性未定义,现在我显示Layer1,现在他的before属性为Layer2的ID。

我的问题:

  
      
  • [2]第3层
  •   
  • 1第2层
  •   
  • [0]第1层
  •   

3层不可见,所以:

  1. Layer2更改为可见->在=未定义之前
  2. Layer3更改为可见->在=未定义之前
  3. Layer1更改为可见->在= Layer2的ID之前

但是,当将Layer3更改为可见时(在步骤2上),则之前的undefined应该是未定义的,之后,当Layer2之前的Layer3 ..的可见性应该是{{1}时, } ID。

重要的是要知道我正在使用react-mapbox-gl,并且在移动和隐藏/显示图层之前需要属性。

之前:字符串传递图层的ID,它将在该ID定义的图层之前显示当前图层。

https://github.com/alex3165/react-mapbox-gl/blob/master/docs/API.md

这是我的代码:

Layer2

2 个答案:

答案 0 :(得分:1)

实际上,我认为有一种更好的方法来设置您的属性。


首先,使用数组存储可见性属性。与下面类似,初始值应为false。

interface InVisiablityProps {
   visible: Array<Boolean>
}

const initialState:InVisiablityProps = {
   invisible: [false,false,false]
}

每次将视图更改为不可见。将属性更改为!(property)

答案 1 :(得分:0)

解决方案:

非常感谢您的帮助和想法,但我已经这样解决了。

在Redux中,我创建了一个新方法,可以在属性更改图层的可见性时在属性之前进行更新,并且当应作为下一层的ID时未定义。

并且,不可能更新changeVisibility内部的该层,因为应该绘制(渲染)更改可见性的层。如果未绘制,则应用程序崩溃,因为before属性具有下一层的ID,并且尚未绘制下一层。

REDUX:

static changeLayerVisibility(layer) {

    let mapLayers = [... AxisStore.getStore().getState().map.mapGLlayers];
    const ids = mapLayers.map(l => l.id);
    const index = ids.indexOf(layer.id);
    const layoutVisibility = (layer.layout.visibility === 'visible') ? 'none' : 'visible';

    let nextVisibleLayer = mapLayers.find((layerObj, idx) => idx > index && layerObj.layout && layerObj.layout.visibility && layerObj.layout.visibility === 'visible');
    let updateLayout = Object.assign({}, mapLayers[index], {
        layout: Object.assign({}, mapLayers[index].layout, { visibility: layoutVisibility }),
        paint: Object.assign({}, mapLayers[index].paint),
        filter: (mapLayers[index].filter) ? Object.assign({}, mapLayers[index].filter) : {},
        before: layoutVisibility === 'visible' && nextVisibleLayer ? nextVisibleLayer.id: undefined,
        visible: (layoutVisibility === 'visible') ? true : false
    });
    if (this.updateLayout.type === 'raster') delete updateLayout.filter;

    mapLayers.splice(index, 1, updateLayout);

    return (dispatch) => {
        dispatch({
            type: MapTypeConstants.SET_MAP_LAYERS,
            payload: mapLayers
        });
    };
}


static updateBefore(layer) {

    let mapLayers = [... AxisStore.getStore().getState().map.mapGLlayers];
    const ids = mapLayers.map(l => l.id);
    const posInRedux = ids.indexOf(layer.id);

    let updateBeforeLayout = Object.assign({}, layer, {
        layout: Object.assign({}, layer.layout),
        paint: Object.assign({}, layer.paint),
        filter: (layer.filter) ? Object.assign({}, layer.filter) : {},
        before: (mapLayers[posInRedux + 1]) ? String(mapLayers[posInRedux + 1].id) : undefined,
        visible: layer.visible
    });
    if (this.updateBeforeLayout.type === 'raster') delete updateBeforeLayout.filter;

    mapLayers.splice(posInRedux, 1, updateBeforeLayout);

    return (dispatch) => {
        dispatch({
            type: MapTypeConstants.SET_MAP_LAYERS,
            payload: mapLayers
        });
    };
}

前端-

changeVisibility(layer) {
    this.props.changeLayerVisibility(layer);
    let layerBeforeUndefined = this.props.mapGLlayers.find(l => l.visible === true && l.before === undefined);
    if (layerBeforeUndefined) {
        setTimeout( () => {
            this.props.updateBefore(layerBeforeUndefined);
        });
    }
};

现在,我想在前面减少代码,因为所有逻辑都必须是一个redux,并且它必须看起来像这样:

changeVisibility(layer) {
    let userMapboxLayers = this.props.map.getStyle().layers.filter(l => l.source && l.source.indexOf('sourceId_') !== -1);
    this.props.changeLayerVisibility(userMapboxLayers, layer);
};