arcgis api for 4.x 开发笔记-在Vue 2.X项目中开发arcgis api for javascript 4.x(七)—— PopupTemplate使用

前言

PopupTemplate 为特定层或图形格式化和定义 Popup 的内容。当选择视图中的要素时,用户还可以使用 PopupTemplate 访问要素属性的值和 Arcade 表达式返回的值。
PopupTemplate 包含 title 和 content 属性,它们充当用于将要素的属性转换为 HTML 表示的模板。语法 {fieldName} 或 {expression/expressionName} 执行参数替换。 Graphic 的默认行为是在单击 Graphic 后显示视图的 Popup。此默认行为需要 PopupTemplate。
PopupTemplate 还允许您格式化 数字(Number)和 日期(Date)字段值并使用 fieldInfos 属性覆盖字段别名。还可以将 操作Actions)添加到模板中,使用户能够执行与要素相关的操作,例如对其进行缩放或根据要素的位置或属性执行查询。

效果

自定义指定featureLayer的popupTemplte点击后弹出的popup,模板代码如下

popup自定义模板

 // 地块图层的popupTemplate
        const dkPopupTemplate = {
            overwriteActions: true,
            outFields: ['*'],
            title: ({ graphic: { attributes } }) => {
                const dkmc = attributes.dkmc;
                return `<div class="flex">
                        <div class="text-cut">${dkmc || ''}</div>
                        </div>`;
            },
            content: ({ graphic: { attributes} }) => {
                const {
                    qylxmc,
                    dkyxztmc,
                    zhdcrq,
                    pjjg_dbs1: pjjg_dbs,
                    pjjg_dxs1: pjjg_dxs,
                    pjjg_tr,
                } = attributes;
                // 地表水和地下水需要转化评价结果值
                const pjjg_dbs_color = this.pjjgValueConversion(pjjg_dbs);
                const pjjg_dxs_color = this.pjjgValueConversion(pjjg_dxs);

                const dcrq = zhdcrq ? moment(zhdcrq)
                    .format('YYYY-MM-DD') : '';

                const tagColor = [ColorEnum.blue, ColorEnum.green, ColorEnum.yellow, ColorEnum.red];

                return `<div class="xf-margin-tb-sm">
                        <div class="text-black-65 flex mb-2" style="white-space: pre;${!qylxmc ? 'display:none;' : ''}"><div class="text-bold" style="word-break: keep-all;">企业类型:</div><div class="text-sm">${qylxmc}</div></div>
                        <div class="text-black-65 flex mb-2" style="white-space: pre;${!dkyxztmc ? 'display:none;' : ''}"><div class="text-bold" style="word-break: keep-all;">生产状态:</div><div class="text-sm">${dkyxztmc}</div></div>
                        <div class="text-black-65 flex mb-2" style="white-space: pre;${!dcrq ? 'display:none;' : ''}"><div class="text-bold" style="word-break: keep-all;">调查日期:</div><div class="text-sm">${dcrq}</div></div>
                        <div class="flex">
                        <div class="ant-tag" style="background-color: ${util.colorHex2RGBA(tagColor[pjjg_dbs_color], 0.1)};color:${tagColor[pjjg_dbs_color]};border:1px solid ${tagColor[pjjg_dbs_color]};${(!rendererFields?.pjjg_dbs?.[pjjg_dbs] || pjjg_dbs == '0') ? 'display:none;' : ''}">
                        地表水:${rendererFields?.pjjg_dbs?.[pjjg_dbs]}
                        </div>
                        <div class="ant-tag" style="background-color: ${util.colorHex2RGBA(tagColor[pjjg_dxs_color], 0.1)};color:${tagColor[pjjg_dxs_color]};border:1px solid ${tagColor[pjjg_dxs_color]};${(!rendererFields?.pjjg_dxs?.[pjjg_dxs] || pjjg_dxs == '0') ? 'display:none;' : ''}">
                        地下水:${rendererFields?.pjjg_dxs?.[pjjg_dxs]}
                        </div>
                        <div class="ant-tag" style="background-color: ${util.colorHex2RGBA(tagColor[pjjg_tr], 0.1)};color:${tagColor[pjjg_tr]};border:1px solid ${tagColor[pjjg_tr]};${(!rendererFields?.pjjg_tr?.[pjjg_tr] || pjjg_tr == '0') ? 'display:none;' : ''}">
                        土壤:${rendererFields?.pjjg_tr?.[pjjg_tr]}
                        </div>
                        </div>
                        </div>`;
            },
            actions: [
                {
                    title: '详情',
                    id: 'showDKDetail',
                    className: 'esri-icon-zoom-in-magnifying-glass',
                },
                {
                    title: '空间分析',
                    id: 'showSpatialAnalysis',
                    className: 'esri-icon-applications',
                },
            ],
        };

代码解析

上边模板代码主要有三部分 title、contentactions 组成,其中title和content都是一个 function函数,最后返回的也是 HTML 的字符串,里面的内容可以通过function返回的graphic里的attributes属性取值动态拼接。

重点看一下 Actions,这是一个对象集合,每个对象代表一个Action或者功能,可以通过单击弹出窗口中象征它们的图标或图像来执行。弹出窗口中每个Action的顺序与它们在Action集合中出现的顺序相同。 每次单击弹出窗口中的Action按钮时,都会触发 Popup 中的 Popup 事件。 此事件应用于为每个单击的操作执行自定义代码。事件监听如下:

    // 初始化activeView的监听事件
    initActiveViewEvents() {
        if (this.activeView) {
            // PopupViewModel的触发动作被触发,然后检查动作id
            this.activeView.popup.on('trigger-action', ({ action }) => {
                const actionId = action?.id;
                 // 点击"地块详情"
                if (actionId === 'showDKDetail') {
                    //获取弹出的popup所归属的graphic的attributes 
                    let { attributes } = this?.activeView?.popup?.viewModel?.selectedFeature;
                    this.handleQuery(() => {
                        // 地块详情页
                        this.$router.push({
                            name: 'dkListDetailPage',
                            query: { id: attributes?.hid, is_cydc: attributes?.is_cydc },
                        });
                    });
                } else if (actionId === 'showSpatialAnalysis') { // 空间分析
                    const selectedFeature = this?.activeView?.popup?.viewModel?.selectedFeature;
                    const { geometry } = selectedFeature;
                    let { attributes } = selectedFeature;
                    attributes = this.formatFeatureAttributeValue(attributes);
                    // 如果选中要素不是polygon,就要进一步处理
                    if (geometry?.type !== 'polygon') {
                        // 地块
                        if (attributes?.hasOwnProperty('dkmc')) {
                            // 由于没有直接能取到“is_cydc”,所以就要先到地块图层进行查询
                            const { subMapLayerIds } = window?.DynamicDataLayersConfig;
                            const mapLayerId = window.LayersConfig.QYDK_M_LayerName;
                            const sqlWhereApi = new CreateSqlWhere();
                            const fieldNamePrefix = this.DynamicDataLayerServiceApi.getJoinDataLayerFieldNamePrefix('', mapLayerId);
                            const sqlWhere: string = sqlWhereApi.eq(`${fieldNamePrefix}hid`, attributes?.hid)
                                .getSql();
                            this.getDynamicDataLayerServiceApi.findFeaturesByQueryConditionsParams(subMapLayerIds[mapLayerId], sqlWhere, undefined, undefined, ([feature]) => {
                                const { geometry: targetGeometry }: any = feature;
                                if (targetGeometry) {
                                    this.startSpatialAnalysis(targetGeometry);
                                }
                            }, { outFields: null });
                        } else { // 样点
                            this.startSpatialAnalysis(geometry);
                        }
                    } else {
                        this.startSpatialAnalysis(geometry);
                    }
                }
            });
        }
    }

主要就是监听地图view的popup的**“trigger-action”**事件,通过上边Actions里Action的id进行区分,完成每个Action的实现功能。

进阶

在实际开发中还有一个很合理的需求,以上面的popup为例,同一个要素图层的使用的都是同一个popupTemplate,所以Actions集合的配置也是不变的,但是因为有些graphic缺少空间分析功能所需要的属性数据,所以我们就应该动态更新空间分析Action的visible。

我没有在官网找到现成的例子,只能通监听地图view弹出的popup所归属的要素(“selectedFeature”),并通过判断动态的控制Action的显示/隐藏,代码如下:

      // 初始化activeView的监听事件
    initActiveViewEvents(activeView = this.activeView) {
        if (activeView) {
            // 监听需要popup选中的feature,动态显示/隐藏action的菜单
            activeView.popup.watch('selectedFeature', (graphic) => {
                if (graphic) {
                    let { attributes: { type } } = graphic;
                    //获取当前要素拥有的popupTemplate模板数据
                    const graphicTemplate = graphic.getEffectivePopupTemplate();

                    // 地块详情展示Action
                    const showDKDetailAction = graphicTemplate?.actions?.items?.find(({ id }) => id === 'showDKDetail');
                    if (showDKDetailAction) {
                        showDKDetailAction.visible = type === ydlxEnum.dk;
                    }

                    // 空间分析展示Action
                    const showSpatialAnalysisAction = graphicTemplate?.actions?.items?.find(({ id }) => id === 'showSpatialAnalysis');
                    if (showSpatialAnalysisAction) {
                        showSpatialAnalysisAction.visible = ydlxEnum.dk;
                    }
                }
            });
        }
    }

参考:官网popupTemplate文档

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
要实现使用 QueryTask 绘制多边形查询并将查询结果以表格形式返回,需要进行以下步骤: 1. 引入 ArcGIS API For JavaScript 3.X 版本和 Vue 框架。 2. 在 Vue 实例创建地图,并添加绘图工具和表格。 ```javascript // 创建地图 var map = new esri.Map("map", { basemap: "streets" }); // 添加绘图工具 var tb = new esri.toolbars.Draw(map); tb.on("draw-end", doQuery); // 添加表格 new Vue({ el: '#table', data: { features: [] } }); ``` 3. 在绘制完成后触发 doQuery 函数进行查询。 ```javascript function doQuery(evt) { tb.deactivate(); var query = new esri.tasks.Query(); query.geometry = evt.geometry; query.outFields = ["*"]; // 查询所有字段 var queryTask = new esri.tasks.QueryTask("your service url"); queryTask.execute(query, showResults); // 执行查询 } ``` 4. 在 showResults 函数处理查询结果,并将结果渲染到表格。 ```javascript function showResults(featureSet) { var features = featureSet.features; var data = []; for (var i = 0; i < features.length; i++) { var feature = features[i]; var attributes = feature.attributes; var row = []; for (var j in attributes) { row.push(attributes[j]); } data.push(row); } // 渲染表格 var app = new Vue({ el: '#table', data: { features: data } }); } ``` 完整代码示例: ```html <!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> <meta name="viewport" content="initial-scale=1, maximum-scale=1,user-scalable=no" /> <title>QueryTask Demo</title> <link rel="stylesheet" href="https://js.arcgis.com/3.38/esri/css/esri.css"> <style> #map { width: 100%; height: 500px; } #table { margin-top: 20px; } </style> </head> <body> <div id="map"></div> <div id="table"> <table> <thead> <tr> <th>Field 1</th> <th>Field 2</th> <th>Field 3</th> </tr> </thead> <tbody> <tr v-for="feature in features"> <td>{{feature[0]}}</td> <td>{{feature[1]}}</td> <td>{{feature[2]}}</td> </tr> </tbody> </table> </div> <script src="https://cdn.bootcdn.net/ajax/libs/vue/2.6.14/vue.min.js"></script> <script src="https://js.arcgis.com/3.38/"></script> <script> var map = new esri.Map("map", { basemap: "streets" }); // 添加绘图工具 var tb = new esri.toolbars.Draw(map); tb.on("draw-end", doQuery); // 添加表格 new Vue({ el: '#table', data: { features: [] } }); function doQuery(evt) { tb.deactivate(); var query = new esri.tasks.Query(); query.geometry = evt.geometry; query.outFields = ["*"]; // 查询所有字段 var queryTask = new esri.tasks.QueryTask("your service url"); queryTask.execute(query, showResults); } function showResults(featureSet) { var features = featureSet.features; var data = []; for (var i = 0; i < features.length; i++) { var feature = features[i]; var attributes = feature.attributes; var row = []; for (var j in attributes) { row.push(attributes[j]); } data.push(row); } // 渲染表格 var app = new Vue({ el: '#table', data: { features: data } }); } </script> </body> </html> ```

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

花姐夫Jun

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值