arcgis-editing-advanced
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseArcGIS Advanced Editing
ArcGIS 高级编辑
Use this skill for advanced editing features including subtypes, forms, versioning, and editor configuration.
Note: For basic editing, use thecomponent. This skill covers advanced configurations that require the Core API.arcgis-editor
本技能适用于包含子类型、表单、版本控制和编辑器配置的高级编辑功能。
注意: 基础编辑请使用组件。本技能涵盖需要Core API的高级配置。arcgis-editor
Editor Component (Basic)
编辑器组件(基础版)
html
<arcgis-map item-id="YOUR_EDITABLE_WEBMAP_ID">
<arcgis-editor slot="top-right"></arcgis-editor>
</arcgis-map>html
<arcgis-map item-id="YOUR_EDITABLE_WEBMAP_ID">
<arcgis-editor slot="top-right"></arcgis-editor>
</arcgis-map>Editor Configuration (Advanced)
编辑器配置(高级版)
Configurable Editor
可配置编辑器
javascript
import Editor from "@arcgis/core/widgets/Editor.js";
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
formTemplate: {
title: "Feature Details",
description: "Enter feature information",
elements: [
{
type: "field",
fieldName: "name",
label: "Name",
description: "Enter the feature name"
},
{
type: "field",
fieldName: "category",
label: "Category"
}
]
},
// Enable/disable operations
addEnabled: true,
updateEnabled: true,
deleteEnabled: false
}]
});
view.ui.add(editor, "top-right");javascript
import Editor from "@arcgis/core/widgets/Editor.js";
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
formTemplate: {
title: "Feature Details",
description: "Enter feature information",
elements: [
{
type: "field",
fieldName: "name",
label: "Name",
description: "Enter the feature name"
},
{
type: "field",
fieldName: "category",
label: "Category"
}
]
},
// Enable/disable operations
addEnabled: true,
updateEnabled: true,
deleteEnabled: false
}]
});
view.ui.add(editor, "top-right");Editor with Field Configuration
带字段配置的编辑器
javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
fieldConfig: [
{
name: "status",
label: "Status",
editable: true,
required: true
},
{
name: "created_date",
label: "Created",
editable: false // Read-only
},
{
name: "comments",
label: "Comments",
editable: true,
maxLength: 500
}
]
}]
});javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
fieldConfig: [
{
name: "status",
label: "Status",
editable: true,
required: true
},
{
name: "created_date",
label: "Created",
editable: false // Read-only
},
{
name: "comments",
label: "Comments",
editable: true,
maxLength: 500
}
]
}]
});Feature Form
要素表单
Standalone Feature Form
独立要素表单
javascript
import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";
const form = new FeatureForm({
container: "formDiv",
layer: featureLayer,
formTemplate: {
title: "Edit Feature",
elements: [
{
type: "field",
fieldName: "name",
label: "Name"
},
{
type: "group",
label: "Location Details",
elements: [
{ type: "field", fieldName: "address" },
{ type: "field", fieldName: "city" },
{ type: "field", fieldName: "zip" }
]
}
]
}
});
// Set feature to edit
form.feature = graphic;
// Listen for submit
form.on("submit", async () => {
if (form.valid) {
const values = form.getValues();
graphic.attributes = { ...graphic.attributes, ...values };
await featureLayer.applyEdits({
updateFeatures: [graphic]
});
}
});javascript
import FeatureForm from "@arcgis/core/widgets/FeatureForm.js";
const form = new FeatureForm({
container: "formDiv",
layer: featureLayer,
formTemplate: {
title: "Edit Feature",
elements: [
{
type: "field",
fieldName: "name",
label: "Name"
},
{
type: "group",
label: "Location Details",
elements: [
{ type: "field", fieldName: "address" },
{ type: "field", fieldName: "city" },
{ type: "field", fieldName: "zip" }
]
}
]
}
});
// Set feature to edit
form.feature = graphic;
// Listen for submit
form.on("submit", async () => {
if (form.valid) {
const values = form.getValues();
graphic.attributes = { ...graphic.attributes, ...values };
await featureLayer.applyEdits({
updateFeatures: [graphic]
});
}
});Form with Grouped Elements
带分组元素的表单
javascript
const formTemplate = {
title: "Asset Details",
elements: [
{
type: "group",
label: "Basic Information",
elements: [
{ type: "field", fieldName: "asset_id" },
{ type: "field", fieldName: "asset_name" },
{ type: "field", fieldName: "asset_type" }
]
},
{
type: "group",
label: "Maintenance",
elements: [
{ type: "field", fieldName: "last_inspection" },
{ type: "field", fieldName: "next_inspection" },
{ type: "field", fieldName: "condition" }
]
}
]
};javascript
const formTemplate = {
title: "Asset Details",
elements: [
{
type: "group",
label: "Basic Information",
elements: [
{ type: "field", fieldName: "asset_id" },
{ type: "field", fieldName: "asset_name" },
{ type: "field", fieldName: "asset_type" }
]
},
{
type: "group",
label: "Maintenance",
elements: [
{ type: "field", fieldName: "last_inspection" },
{ type: "field", fieldName: "next_inspection" },
{ type: "field", fieldName: "condition" }
]
}
]
};Expression-Based Visibility
基于表达式的可见性
javascript
const formTemplate = {
elements: [
{
type: "field",
fieldName: "type"
},
{
type: "field",
fieldName: "subtype",
visibilityExpression: "type-requires-subtype"
}
],
expressionInfos: [{
name: "type-requires-subtype",
expression: "$feature.type == 'complex'"
}]
};javascript
const formTemplate = {
elements: [
{
type: "field",
fieldName: "type"
},
{
type: "field",
fieldName: "subtype",
visibilityExpression: "type-requires-subtype"
}
],
expressionInfos: [{
name: "type-requires-subtype",
expression: "$feature.type == 'complex'"
}]
};Subtypes
子类型
Working with Subtypes
处理子类型
javascript
// Layer with subtypes
const layer = new FeatureLayer({
url: "https://services.arcgis.com/.../FeatureServer/0"
});
await layer.load();
// Get subtype info
const subtypeField = layer.subtypeField;
const subtypes = layer.subtypes;
subtypes.forEach(subtype => {
console.log("Code:", subtype.code);
console.log("Name:", subtype.name);
console.log("Default values:", subtype.defaultValues);
});javascript
// Layer with subtypes
const layer = new FeatureLayer({
url: "https://services.arcgis.com/.../FeatureServer/0"
});
await layer.load();
// Get subtype info
const subtypeField = layer.subtypeField;
const subtypes = layer.subtypes;
subtypes.forEach(subtype => {
console.log("Code:", subtype.code);
console.log("Name:", subtype.name);
console.log("Default values:", subtype.defaultValues);
});Subtype Group Layer
子类型分组图层
javascript
import SubtypeGroupLayer from "@arcgis/core/layers/SubtypeGroupLayer.js";
const subtypeLayer = new SubtypeGroupLayer({
url: "https://services.arcgis.com/.../FeatureServer/0"
});
await subtypeLayer.load();
// Access sublayers by subtype
subtypeLayer.sublayers.forEach(sublayer => {
console.log("Subtype:", sublayer.subtypeCode, sublayer.title);
// Each sublayer can have different renderer/popup
});javascript
import SubtypeGroupLayer from "@arcgis/core/layers/SubtypeGroupLayer.js";
const subtypeLayer = new SubtypeGroupLayer({
url: "https://services.arcgis.com/.../FeatureServer/0"
});
await subtypeLayer.load();
// Access sublayers by subtype
subtypeLayer.sublayers.forEach(sublayer => {
console.log("Subtype:", sublayer.subtypeCode, sublayer.title);
// Each sublayer can have different renderer/popup
});Editor with Subtype Support
支持子类型的编辑器
javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: subtypeGroupLayer,
// Editor automatically handles subtypes
addEnabled: true,
updateEnabled: true
}]
});javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: subtypeGroupLayer,
// Editor automatically handles subtypes
addEnabled: true,
updateEnabled: true
}]
});Versioning
版本控制
Branch Versioning Overview
分支版本控制概述
Branch versioning allows multiple users to edit the same data simultaneously without conflicts until reconciliation.
javascript
import VersionManagementService from "@arcgis/core/versionManagement/VersionManagementService.js";
const vms = new VersionManagementService({
url: "https://services.arcgis.com/.../VersionManagementServer"
});
await vms.load();
console.log("Default version:", vms.defaultVersionName);
console.log("Supports versioning:", vms.supportsVersioning);分支版本允许多个用户同时编辑同一数据,直到调和阶段才会处理冲突。
javascript
import VersionManagementService from "@arcgis/core/versionManagement/VersionManagementService.js";
const vms = new VersionManagementService({
url: "https://services.arcgis.com/.../VersionManagementServer"
});
await vms.load();
console.log("Default version:", vms.defaultVersionName);
console.log("Supports versioning:", vms.supportsVersioning);Get Version Information
获取版本信息
javascript
// Get all versions
const versions = await vms.getVersionInfos();
versions.forEach(v => {
console.log("Version:", v.versionName);
console.log(" Owner:", v.versionOwner);
console.log(" Description:", v.description);
console.log(" Access:", v.access); // public, protected, private
console.log(" Parent:", v.parentVersionName);
console.log(" Created:", v.creationDate);
console.log(" Modified:", v.modifiedDate);
});
// Get specific version info
const versionInfo = await vms.getVersionInfo({
versionName: "sde.MyVersion"
});javascript
// Get all versions
const versions = await vms.getVersionInfos();
versions.forEach(v => {
console.log("Version:", v.versionName);
console.log(" Owner:", v.versionOwner);
console.log(" Description:", v.description);
console.log(" Access:", v.access); // public, protected, private
console.log(" Parent:", v.parentVersionName);
console.log(" Created:", v.creationDate);
console.log(" Modified:", v.modifiedDate);
});
// Get specific version info
const versionInfo = await vms.getVersionInfo({
versionName: "sde.MyVersion"
});Create Version
创建版本
javascript
// Create new version
const newVersion = await vms.createVersion({
versionName: "MyEditVersion",
description: "Version for editing project X",
access: "private", // public, protected, private
parentVersionName: "sde.DEFAULT" // Optional, defaults to DEFAULT
});
console.log("Created version:", newVersion.versionName);
console.log("Version GUID:", newVersion.versionGuid);javascript
// Create new version
const newVersion = await vms.createVersion({
versionName: "MyEditVersion",
description: "Version for editing project X",
access: "private", // public, protected, private
parentVersionName: "sde.DEFAULT" // Optional, defaults to DEFAULT
});
console.log("Created version:", newVersion.versionName);
console.log("Version GUID:", newVersion.versionGuid);Delete Version
删除版本
javascript
// Delete a version (must be owner or admin)
await vms.deleteVersion({
versionName: "sde.MyEditVersion"
});javascript
// Delete a version (must be owner or admin)
await vms.deleteVersion({
versionName: "sde.MyEditVersion"
});Alter Version
修改版本
javascript
// Modify version properties
await vms.alterVersion({
versionName: "sde.MyEditVersion",
description: "Updated description",
access: "protected", // Change access level
ownerName: "newOwner" // Transfer ownership (admin only)
});javascript
// Modify version properties
await vms.alterVersion({
versionName: "sde.MyEditVersion",
description: "Updated description",
access: "protected", // Change access level
ownerName: "newOwner" // Transfer ownership (admin only)
});Switching Versions
切换版本
javascript
// Set version on layer at creation
const featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/.../FeatureServer/0",
gdbVersion: "sde.MyEditVersion"
});
// Or change version dynamically
await featureLayer.load();
featureLayer.gdbVersion = "sde.AnotherVersion";
await featureLayer.refresh();
// Switch all layers in map
map.layers.forEach(layer => {
if (layer.gdbVersion !== undefined) {
layer.gdbVersion = "sde.MyEditVersion";
layer.refresh();
}
});javascript
// Set version on layer at creation
const featureLayer = new FeatureLayer({
url: "https://services.arcgis.com/.../FeatureServer/0",
gdbVersion: "sde.MyEditVersion"
});
// Or change version dynamically
await featureLayer.load();
featureLayer.gdbVersion = "sde.AnotherVersion";
await featureLayer.refresh();
// Switch all layers in map
map.layers.forEach(layer => {
if (layer.gdbVersion !== undefined) {
layer.gdbVersion = "sde.MyEditVersion";
layer.refresh();
}
});Start/Stop Edit Session
启动/停止编辑会话
javascript
// Start editing session
const session = await vms.startReading({
versionName: "sde.MyEditVersion"
});
const sessionId = session.sessionId;
// For write access
const writeSession = await vms.startEditing({
versionName: "sde.MyEditVersion"
});
// Stop session when done
await vms.stopEditing({
sessionId: sessionId,
saveEdits: true // or false to discard
});javascript
// Start editing session
const session = await vms.startReading({
versionName: "sde.MyEditVersion"
});
const sessionId = session.sessionId;
// For write access
const writeSession = await vms.startEditing({
versionName: "sde.MyEditVersion"
});
// Stop session when done
await vms.stopEditing({
sessionId: sessionId,
saveEdits: true // or false to discard
});Version Reconcile and Post
版本调和与提交
javascript
// Reconcile version with parent
const reconcileResult = await vms.reconcile({
sessionId: sessionId,
abortIfConflicts: false,
conflictDetection: "byAttribute", // byAttribute, byObject
withPost: false,
conflictResolution: "favorEditVersion" // favorEditVersion, favorTargetVersion
});
console.log("Has conflicts:", reconcileResult.hasConflicts);
console.log("Conflicts removed:", reconcileResult.conflictsRemoved);
if (!reconcileResult.hasConflicts) {
// Post changes to parent version
await vms.post({ sessionId });
console.log("Changes posted successfully");
}javascript
// Reconcile version with parent
const reconcileResult = await vms.reconcile({
sessionId: sessionId,
abortIfConflicts: false,
conflictDetection: "byAttribute", // byAttribute, byObject
withPost: false,
conflictResolution: "favorEditVersion" // favorEditVersion, favorTargetVersion
});
console.log("Has conflicts:", reconcileResult.hasConflicts);
console.log("Conflicts removed:", reconcileResult.conflictsRemoved);
if (!reconcileResult.hasConflicts) {
// Post changes to parent version
await vms.post({ sessionId });
console.log("Changes posted successfully");
}Conflict Detection and Resolution
冲突检测与解决
javascript
// Check for conflicts before reconcile
const conflictResult = await vms.reconcile({
sessionId: sessionId,
abortIfConflicts: true, // Stop if conflicts found
conflictDetection: "byAttribute"
});
if (conflictResult.hasConflicts) {
// Get conflict details
console.log("Conflicts found, manual resolution needed");
// Resolve conflicts by favoring edit version
const resolveResult = await vms.reconcile({
sessionId: sessionId,
abortIfConflicts: false,
conflictResolution: "favorEditVersion",
withPost: true
});
}javascript
// Check for conflicts before reconcile
const conflictResult = await vms.reconcile({
sessionId: sessionId,
abortIfConflicts: true, // Stop if conflicts found
conflictDetection: "byAttribute"
});
if (conflictResult.hasConflicts) {
// Get conflict details
console.log("Conflicts found, manual resolution needed");
// Resolve conflicts by favoring edit version
const resolveResult = await vms.reconcile({
sessionId: sessionId,
abortIfConflicts: false,
conflictResolution: "favorEditVersion",
withPost: true
});
}Version Differences
版本差异
javascript
// Get differences between versions
const differences = await vms.getVersionDifferences({
sessionId: sessionId,
fromMoment: "commonAncestor", // commonAncestor, now
layers: ["0", "1"] // Layer IDs to compare
});
differences.forEach(diff => {
console.log("Layer:", diff.layerId);
console.log("Inserts:", diff.inserts);
console.log("Updates:", diff.updates);
console.log("Deletes:", diff.deletes);
});javascript
// Get differences between versions
const differences = await vms.getVersionDifferences({
sessionId: sessionId,
fromMoment: "commonAncestor", // commonAncestor, now
layers: ["0", "1"] // Layer IDs to compare
});
differences.forEach(diff => {
console.log("Layer:", diff.layerId);
console.log("Inserts:", diff.inserts);
console.log("Updates:", diff.updates);
console.log("Deletes:", diff.deletes);
});Version Lock Management
版本锁管理
javascript
// Get lock status
const lockInfo = await vms.getLockInfo({
versionName: "sde.MyEditVersion"
});
console.log("Is locked:", lockInfo.isLocked);
console.log("Locked by:", lockInfo.lockOwner);
console.log("Lock type:", lockInfo.lockType);
// Acquire exclusive lock
await vms.acquireLock({
versionName: "sde.MyEditVersion",
lockType: "exclusive" // shared, exclusive
});
// Release lock
await vms.releaseLock({
versionName: "sde.MyEditVersion"
});javascript
// Get lock status
const lockInfo = await vms.getLockInfo({
versionName: "sde.MyEditVersion"
});
console.log("Is locked:", lockInfo.isLocked);
console.log("Locked by:", lockInfo.lockOwner);
console.log("Lock type:", lockInfo.lockType);
// Acquire exclusive lock
await vms.acquireLock({
versionName: "sde.MyEditVersion",
lockType: "exclusive" // shared, exclusive
});
// Release lock
await vms.releaseLock({
versionName: "sde.MyEditVersion"
});Validate Network Topology
验证网络拓扑
javascript
// For utility networks - validate topology after edits
const validateResult = await vms.validateNetworkTopology({
sessionId: sessionId,
validateArea: extent, // Optional extent to validate
validationType: "normal" // normal, rebuild
});
console.log("Validation success:", validateResult.success);
console.log("Dirty areas remaining:", validateResult.dirtyAreaCount);javascript
// For utility networks - validate topology after edits
const validateResult = await vms.validateNetworkTopology({
sessionId: sessionId,
validateArea: extent, // Optional extent to validate
validationType: "normal" // normal, rebuild
});
console.log("Validation success:", validateResult.success);
console.log("Dirty areas remaining:", validateResult.dirtyAreaCount);Complete Version Workflow
完整版本工作流
javascript
async function editInVersion(vms, featureLayer, edits) {
// 1. Create version
const version = await vms.createVersion({
versionName: `Edit_${Date.now()}`,
description: "Temporary edit version",
access: "private"
});
try {
// 2. Switch layer to version
featureLayer.gdbVersion = version.versionName;
await featureLayer.refresh();
// 3. Start edit session
const session = await vms.startEditing({
versionName: version.versionName
});
// 4. Apply edits
await featureLayer.applyEdits(edits);
// 5. Reconcile with parent
const reconcileResult = await vms.reconcile({
sessionId: session.sessionId,
abortIfConflicts: false,
conflictResolution: "favorEditVersion",
withPost: false
});
if (reconcileResult.hasConflicts) {
throw new Error("Conflicts detected during reconcile");
}
// 6. Post to parent
await vms.post({ sessionId: session.sessionId });
// 7. Stop editing
await vms.stopEditing({
sessionId: session.sessionId,
saveEdits: true
});
console.log("Edits posted successfully");
} finally {
// 8. Switch back to default and delete temp version
featureLayer.gdbVersion = vms.defaultVersionName;
await featureLayer.refresh();
await vms.deleteVersion({
versionName: version.versionName
});
}
}javascript
async function editInVersion(vms, featureLayer, edits) {
// 1. Create version
const version = await vms.createVersion({
versionName: `Edit_${Date.now()}`,
description: "Temporary edit version",
access: "private"
});
try {
// 2. Switch layer to version
featureLayer.gdbVersion = version.versionName;
await featureLayer.refresh();
// 3. Start edit session
const session = await vms.startEditing({
versionName: version.versionName
});
// 4. Apply edits
await featureLayer.applyEdits(edits);
// 5. Reconcile with parent
const reconcileResult = await vms.reconcile({
sessionId: session.sessionId,
abortIfConflicts: false,
conflictResolution: "favorEditVersion",
withPost: false
});
if (reconcileResult.hasConflicts) {
throw new Error("Conflicts detected during reconcile");
}
// 6. Post to parent
await vms.post({ sessionId: session.sessionId });
// 7. Stop editing
await vms.stopEditing({
sessionId: session.sessionId,
saveEdits: true
});
console.log("Edits posted successfully");
} finally {
// 8. Switch back to default and delete temp version
featureLayer.gdbVersion = vms.defaultVersionName;
await featureLayer.refresh();
await vms.deleteVersion({
versionName: version.versionName
});
}
}Related Records
关联记录
Query Related Records
查询关联记录
javascript
const relatedRecords = await layer.queryRelatedFeatures({
outFields: ["*"],
relationshipId: 0,
objectIds: [selectedFeature.attributes.OBJECTID]
});
relatedRecords[selectedObjectId].features.forEach(related => {
console.log("Related:", related.attributes);
});javascript
const relatedRecords = await layer.queryRelatedFeatures({
outFields: ["*"],
relationshipId: 0,
objectIds: [selectedFeature.attributes.OBJECTID]
});
relatedRecords[selectedObjectId].features.forEach(related => {
console.log("Related:", related.attributes);
});Edit Related Records in Form
在表单中编辑关联记录
javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: parentLayer,
// Include related tables
relatedTableInfos: [{
layer: relatedTable,
addEnabled: true,
updateEnabled: true,
deleteEnabled: true
}]
}]
});javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: parentLayer,
// Include related tables
relatedTableInfos: [{
layer: relatedTable,
addEnabled: true,
updateEnabled: true,
deleteEnabled: true
}]
}]
});Attachments
附件
Enable Attachments in Editor
在编辑器中启用附件
javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
attachmentsOnCreateEnabled: true,
attachmentsOnUpdateEnabled: true
}]
});javascript
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
attachmentsOnCreateEnabled: true,
attachmentsOnUpdateEnabled: true
}]
});Programmatic Attachment Handling
程序化处理附件
javascript
// Query attachments
const attachments = await layer.queryAttachments({
objectIds: [featureOID]
});
// Add attachment
const formData = new FormData();
formData.append("attachment", fileBlob, "photo.jpg");
await layer.addAttachment(featureOID, formData);
// Delete attachment
await layer.deleteAttachments(featureOID, [attachmentId]);javascript
// Query attachments
const attachments = await layer.queryAttachments({
objectIds: [featureOID]
});
// Add attachment
const formData = new FormData();
formData.append("attachment", fileBlob, "photo.jpg");
await layer.addAttachment(featureOID, formData);
// Delete attachment
await layer.deleteAttachments(featureOID, [attachmentId]);Validation
验证
Form Validation
表单验证
javascript
const form = new FeatureForm({
layer: featureLayer,
formTemplate: {
elements: [{
type: "field",
fieldName: "email",
label: "Email",
validationExpression: {
expression: `
var email = $feature.email;
return IIf(Find("@", email) > 0, true, { valid: false, errorMessage: "Invalid email" });
`
}
}]
}
});
// Check validity before submit
if (form.valid) {
// Submit
} else {
// Show validation errors
}javascript
const form = new FeatureForm({
layer: featureLayer,
formTemplate: {
elements: [{
type: "field",
fieldName: "email",
label: "Email",
validationExpression: {
expression: `
var email = $feature.email;
return IIf(Find("@", email) > 0, true, { valid: false, errorMessage: "Invalid email" });
`
}
}]
}
});
// Check validity before submit
if (form.valid) {
// Submit
} else {
// Show validation errors
}Complete Example
完整示例
html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://js.arcgis.com/4.34/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.34/"></script>
<style>
html, body, #viewDiv { height: 100%; margin: 0; }
#formPanel { position: absolute; top: 10px; right: 10px; width: 300px; }
</style>
<script type="module">
import Map from "@arcgis/core/Map.js";
import MapView from "@arcgis/core/views/MapView.js";
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
import Editor from "@arcgis/core/widgets/Editor.js";
const layer = new FeatureLayer({
url: "https://services.arcgis.com/.../FeatureServer/0"
});
const map = new Map({
basemap: "streets-navigation-vector",
layers: [layer]
});
const view = new MapView({
container: "viewDiv",
map: map
});
const editor = new Editor({
view: view,
layerInfos: [{
layer: layer,
formTemplate: {
title: "Edit Feature",
elements: [
{
type: "group",
label: "Details",
elements: [
{ type: "field", fieldName: "name", label: "Name" },
{ type: "field", fieldName: "type", label: "Type" },
{ type: "field", fieldName: "status", label: "Status" }
]
}
]
},
attachmentsOnCreateEnabled: true,
attachmentsOnUpdateEnabled: true
}]
});
view.ui.add(editor, "top-right");
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>html
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://js.arcgis.com/4.34/esri/themes/light/main.css" />
<script src="https://js.arcgis.com/4.34/"></script>
<style>
html, body, #viewDiv { height: 100%; margin: 0; }
#formPanel { position: absolute; top: 10px; right: 10px; width: 300px; }
</style>
<script type="module">
import Map from "@arcgis/core/Map.js";
import MapView from "@arcgis/core/views/MapView.js";
import FeatureLayer from "@arcgis/core/layers/FeatureLayer.js";
import Editor from "@arcgis/core/widgets/Editor.js";
const layer = new FeatureLayer({
url: "https://services.arcgis.com/.../FeatureServer/0"
});
const map = new Map({
basemap: "streets-navigation-vector",
layers: [layer]
});
const view = new MapView({
container: "viewDiv",
map: map
});
const editor = new Editor({
view: view,
layerInfos: [{
layer: layer,
formTemplate: {
title: "Edit Feature",
elements: [
{
type: "group",
label: "Details",
elements: [
{ type: "field", fieldName: "name", label: "Name" },
{ type: "field", fieldName: "type", label: "Type" },
{ type: "field", fieldName: "status", label: "Status" }
]
}
]
},
attachmentsOnCreateEnabled: true,
attachmentsOnUpdateEnabled: true
}]
});
view.ui.add(editor, "top-right");
</script>
</head>
<body>
<div id="viewDiv"></div>
</body>
</html>TypeScript Usage
TypeScript 使用
Form elements use autocasting with properties. For TypeScript safety, use :
typeas consttypescript
// Use 'as const' for type safety in editor configurations
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
formTemplate: {
title: "Feature Details",
elements: [
{ type: "field", fieldName: "name" },
{ type: "field", fieldName: "category" }
]
} as const
}]
});Tip: See arcgis-core-maps skill for detailed guidance on autocasting vs explicit classes.
表单元素通过属性自动类型转换。为保证TypeScript类型安全,请使用:
typeas consttypescript
// Use 'as const' for type safety in editor configurations
const editor = new Editor({
view: view,
layerInfos: [{
layer: featureLayer,
formTemplate: {
title: "Feature Details",
elements: [
{ type: "field", fieldName: "name" },
{ type: "field", fieldName: "category" }
]
} as const
}]
});提示: 有关自动类型转换与显式类的详细说明,请查看arcgis-core-maps 技能。
Common Pitfalls
常见陷阱
-
Editing permissions: User must have edit permissions on the layer
-
Subtype field: Must match the subtype configuration in the service
-
Version locking: Branch versions may lock during editing sessions
-
Validation expressions: Must return true/false or error object
-
Related records: Require proper relationship configuration in service
-
编辑权限:用户必须拥有该图层的编辑权限
-
子类型字段:必须与服务中的子类型配置匹配
-
版本锁定:分支版本可能在编辑会话期间被锁定
-
验证表达式:必须返回true/false或错误对象
-
关联记录:需要在服务中正确配置关系