使用 GraphicsLayer 时弹出窗口无法正确隐藏字段 - ArcGIS Javascript API 4.x

2023-12-06

使用 ArcGIS API Javascript 4.x 和 GraphicsLayer,弹出窗口无法正确隐藏字段。它与 FeatureLayer 一起工作正常,但我需要使用 GraphicsLayer 来满足此请求。下面附上一个重现该错误的完整工作示例。

如何重现问题:

如果您首先单击左侧三角形,它会正常工作并显示所有字段。但是,如果您先单击右侧三角形,然后单击左侧三角形,则不会显示左侧三角形的所有字段。

注意:在执行上述两个测试之前,请务必单击“运行代码片段”以重置页面。

这是重现该问题的完整代码:

    <html lang="en">

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <title>
            Custom popup actions per feature attribute | JavaScript 4.27
        </title>

        <style>
            body {
                padding: 0;
                margin: 0;
                height: 100%;
                width: 100%;
                overflow: hidden;
            }

            #viewDiv {
                position: absolute;
                right: 0;
                left: 0;
                top: 0;
                bottom: 0;
            }
        </style>

        <link rel="stylesheet" href="https://js.arcgis.com/4.27/esri/themes/light/main.css" />
        <script src="https://js.arcgis.com/4.27/"></script>

        <script>
            require(["esri/Map", "esri/views/MapView", "esri/layers/GraphicsLayer", "esri/geometry/Polygon","esri/Graphic",
            "esri/PopupTemplate",
            "esri/core/reactiveUtils"], (
                Map,
                MapView,
                GraphicsLayer,
                Polygon,
                Graphic,
                PopupTemplate,
                reactiveUtils
            ) => {
                const map = new Map({
                    basemap: "streets-navigation-vector"
                });

                const view = new MapView({
                    container: "viewDiv",
                    map: map,
                    center: [-112.42914,38.771353],
                    zoom: 5
                });

        /********************
        * Add boundary polygon/symbol
        ********************/
        const boundaryPolygon1 = new Polygon({
            hasZ: false,
            hasM: false,
            rings: [[[-112.42914,38.771353],[-112.324772,38.891169],[-112.571965,38.899720]]]
        });
        
        const boundaryPolygon2 = new Polygon({
            hasZ: false,
            hasM: false,
            rings: [[[-111.52914,38.771353],[-111.424772,38.891169],[-111.671965,38.899720]]]
        });

        const theSymbol = {
            type: "simple-fill",
            style: "solid",
            color: [200, 40, 40, 1],
            outline: {
                color: [255, 0, 0, 255],
                width: 2,
                type: "simple-line",
                style: "solid"
            }
        };

                /********************
                 * Add graphics layer
                 ********************/
                 
let myAtt1 = {
  ObjectID: 1,
  name: "John Ross",
  address: "1234 Main Street"
};

let myAtt2 = {
  ObjectID: 2,
  name: "Bob Cattle",
  address: null
};
                 
                 graphicsLayer = new GraphicsLayer();
                 map.add(graphicsLayer);
 
// Must use shared PopupTemplate since there can be many boundary Graphic objects             
var popTemplate = new PopupTemplate({
            title: "Graphic Test",
                    content: [
                        {
                            type: "fields",
                            fieldInfos: [
                                {
                                    fieldName: "ObjectID"
                                },
                                {
                                    fieldName: "name"
                                },
                                {
                                    fieldName: "address"
                                }
                            ]
                        }
                    ]
        });

const boundaryGraphic1 = new Graphic({
            geometry: boundaryPolygon1,
            symbol: theSymbol,
            attributes: myAtt1,
            popupEnabled: true,
            popupTemplate: popTemplate
        });
        
        const boundaryGraphic2 = new Graphic({
            geometry: boundaryPolygon2,
            symbol: theSymbol,
            attributes: myAtt2,
            popupEnabled: true,
            popupTemplate: popTemplate
        });
        

        view.when(() => {
                graphicsLayer.add(boundaryGraphic1);
                graphicsLayer.add(boundaryGraphic2);
        });

                view.when(() => {
                    // Watch for when features are selected
                    reactiveUtils.watch(() => view.popup.selectedFeature, (graphic) => {
                        if (graphic) {
                            // Get Effective PopupTemplate
                            const graphicTemplate = graphic.getEffectivePopupTemplate();
                           
                            
                            // Hide row if null value
                            for(const fi of graphicTemplate.content[0].fieldInfos) {
                var myfield = graphic.attributes[fi.fieldName];
                                if (!!myfield)
                                {
                                    fi.visible = true;
                                }
                                else    
                               {
                                   fi.visible = false;
                               }
                            }

                        }
                    });

                    
                });
            });
        </script>
    </head>

    <body class="light">
        <div id="viewDiv" class="esri-widget"></div>
    </body>

    </html>

我发现问题了!原始问题中用于观察上述弹出窗口更改的代码是 FeatureLayer 弹出窗口的正确代码。它监视 view.popup.selectedFeature 并使用 getEffectivePopupTemplate 引用弹出模板:

view.when(() => {
                    // Watch for when features are selected
                    reactiveUtils.watch(() => view.popup.selectedFeature, (graphic) => {
                        if (graphic) {
                            // Get Effective PopupTemplate
                            const graphicTemplate = graphic.getEffectivePopupTemplate();
                           
                            
                            // Hide row if null value
                            for(const fi of graphicTemplate.content[0].fieldInfos) {
                var myfield = graphic.attributes[fi.fieldName];
                                if (!!myfield)
                                {
                                    fi.visible = true;
                                }
                                else    
                               {
                                   fi.visible = false;
                               }
                            }

                        }
                    });

                    
                });

然而,使用 GraphicsLayer 观看弹出窗口的代码如下。请注意,我们现在正在观看 view.popup.selectedFeatureWidget 并使用实际模板(widget.graphic.popupTemplate 而不是调用graphic.getEffectivePopupTemplate())。另请注意,属性向下一级(widget.graphic.attributes):

view.when(() => {
                        // Watch for when features are selected
                        reactiveUtils.watch(() => view.popup.selectedFeatureWidget, (widget) => {
                            if (widget && widget.graphic && widget.graphic.popupTemplate) {
                                // Get the graphic popup template
                        const graphicTemplate = widget.graphic.popupTemplate;
                               
                                
                                // Hide row if null value
                                for(const fi of graphicTemplate.content[0].fieldInfos) {
                    var myfield = widget.graphic.attributes[fi.fieldName];
                                    if (!!myfield)
                                    {
                                        fi.visible = true;
                                    }
                                    else    
                                   {
                                       fi.visible = false;
                                   }
                                }

                            }
                        });

                        
                    });
<html lang="en">

    <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="initial-scale=1,maximum-scale=1,user-scalable=no" />
        <title>
            Custom popup actions per feature attribute | JavaScript 4.27
        </title>

        <style>
            body {
                padding: 0;
                margin: 0;
                height: 100%;
                width: 100%;
                overflow: hidden;
            }

            #viewDiv {
                position: absolute;
                right: 0;
                left: 0;
                top: 0;
                bottom: 0;
            }
        </style>

        <link rel="stylesheet" href="https://js.arcgis.com/4.27/esri/themes/light/main.css" />
        <script src="https://js.arcgis.com/4.27/"></script>

        <script>
            require(["esri/Map", "esri/views/MapView", "esri/layers/GraphicsLayer", "esri/geometry/Polygon","esri/Graphic",
            "esri/PopupTemplate",
            "esri/core/reactiveUtils"], (
                Map,
                MapView,
                GraphicsLayer,
                Polygon,
                Graphic,
                PopupTemplate,
                reactiveUtils
            ) => {
                const map = new Map({
                    basemap: "streets-navigation-vector"
                });

                const view = new MapView({
                    container: "viewDiv",
                    map: map,
                    center: [-112.42914,38.771353],
                    zoom: 5
                });

        /********************
        * Add boundary polygon/symbol
        ********************/
        const boundaryPolygon1 = new Polygon({
            hasZ: false,
            hasM: false,
            rings: [[[-112.42914,38.771353],[-112.324772,38.891169],[-112.571965,38.899720]]]
        });
        
        const boundaryPolygon2 = new Polygon({
            hasZ: false,
            hasM: false,
            rings: [[[-111.52914,38.771353],[-111.424772,38.891169],[-111.671965,38.899720]]]
        });

        const theSymbol = {
            type: "simple-fill",
            style: "solid",
            color: [200, 40, 40, 1],
            outline: {
                color: [255, 0, 0, 255],
                width: 2,
                type: "simple-line",
                style: "solid"
            }
        };

                /********************
                 * Add graphics layer
                 ********************/
                 
let myAtt1 = {
  ObjectID: 1,
  name: "John Ross",
  address: "1234 Main Street"
};

let myAtt2 = {
  ObjectID: 2,
  name: "Bob Cattle",
  address: null
};
                 
                 graphicsLayer = new GraphicsLayer();
                 map.add(graphicsLayer);
 
// Must use shared PopupTemplate since there can be many boundary Graphic objects             
var popTemplate = new PopupTemplate({
            title: "Graphic Test",
                    content: [
                        {
                            type: "fields",
                            fieldInfos: [
                                {
                                    fieldName: "ObjectID"
                                },
                                {
                                    fieldName: "name"
                                },
                                {
                                    fieldName: "address"
                                }
                            ]
                        }
                    ]
        });

const boundaryGraphic1 = new Graphic({
            geometry: boundaryPolygon1,
            symbol: theSymbol,
            attributes: myAtt1,
            popupEnabled: true,
            popupTemplate: popTemplate
        });
        
        const boundaryGraphic2 = new Graphic({
            geometry: boundaryPolygon2,
            symbol: theSymbol,
            attributes: myAtt2,
            popupEnabled: true,
            popupTemplate: popTemplate
        });
        

        view.when(() => {
                graphicsLayer.add(boundaryGraphic1);
                graphicsLayer.add(boundaryGraphic2);
        });

                
                
                view.when(() => {
                    // Watch for when features are selected
                    reactiveUtils.watch(() => view.popup.selectedFeatureWidget, (widget) => {
                        if (widget && widget.graphic && widget.graphic.popupTemplate) {
                            // Get the graphic popup template
                    const graphicTemplate = widget.graphic.popupTemplate;
                           
                            
                            // Hide row if null value
                            for(const fi of graphicTemplate.content[0].fieldInfos) {
                var myfield = widget.graphic.attributes[fi.fieldName];
                                if (!!myfield)
                                {
                                    fi.visible = true;
                                }
                                else    
                               {
                                   fi.visible = false;
                               }
                            }

                        }
                    });

                    
                });
                
                
            });
        </script>
    </head>

    <body class="light">
        <div id="viewDiv" class="esri-widget"></div>
    </body>

    </html>
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用 GraphicsLayer 时弹出窗口无法正确隐藏字段 - ArcGIS Javascript API 4.x 的相关文章

随机推荐