Using the canExecute Command Hook
This article will guide you through how to prevent a custom command from executing through the canExecute
hook.
Prerequisites
- Download and setup the VertiGIS Studio Web SDK.
- Check out the deployment instructions to learn more about deploying custom code to a VertiGIS Studio Web App.
Create an App with an IWTM and a Custom Component
First, let's create an app with an IWTM and a custom component that implements a simple command that displays an alert.
- Layout
- App Config
- Component
- Component Model
- Component Index
- Registration
<?xml version="1.0" encoding="UTF-8"?>
<layout xmlns="https://geocortex.com/layout/v1" xmlns:custom="custom.abc123">
<map>
<iwtm config="iwtm-config" slot="top-left" />
<custom:custom-component margin="3" slot="top-center"/>
</map>
</layout>
{
"schemaVersion": "1.0",
"items": [
{
"$type": "menu",
"id": "iwtm-config",
"items": [
{
"$type": "menu-item",
"id": "command-with-can-execute",
"title": "Command With Can Execute",
"iconId": "info",
"action": "custom.command-with-can-execute"
}
],
"title": "I want to..."
}
]
}
import {
LayoutElement,
LayoutElementProperties,
} from "@vertigis/web/components";
import Button from "@vertigis/web/ui/Button";
import React from "react";
import CustomModel from "./CustomModel";
const CustomComponent = (
props: LayoutElementProperties<CustomModel>
) => {
return (
<LayoutElement {...props}>
<Button>Placeholder</Button>
</LayoutElement>
);
};
export default CustomComponent;
import {
ComponentModelBase,
serializable,
} from "@vertigis/web/models";
import { command } from "@vertigis/web/messaging";
@serializable
export default class CustomModel extends ComponentModelBase {
@command("custom.command-with-can-execute")
protected _commandWithCanExecute(): void {
this.messages.commands.ui.alert.execute({
message: "Executed `custom.command-with-can-execute`",
});
}
}
export { default } from "./CustomComponent";
export { default as CustomModel } from "./CustomModel";
import { LibraryRegistry } from "@vertigis/web/config";
import CustomComponent, {
CustomModel,
} from "./components/CustomComponent";
const LAYOUT_NAMESPACE = "custom.abc123";
export default function (registry: LibraryRegistry) {
registry.registerComponent({
name: "custom-component",
namespace: LAYOUT_NAMESPACE,
getComponentType: () => CustomComponent,
itemType: "custom-model",
title: "Custom Component",
});
registry.registerModel({
getModel: (config) => new CustomModel(config),
itemType: "custom-model",
});
registry.registerCommand({
name: "custom.command-with-can-execute",
itemType: "custom-model",
});
}
Add a Button to Toggle the canExecute
Status
Next, let's add a button to the custom component that will toggle the canExecute
status of the custom.command-with-can-execute
command.
- Component
- Component Model
import {
LayoutElement,
LayoutElementProperties,
} from "@vertigis/web/components";
import Button from "@vertigis/web/ui/Button";
import React from "react";
import CustomModel from "./CustomModel";
const CustomComponent = (
props: LayoutElementProperties<CustomModel>
) => {
const { model } = props;
return (
<LayoutElement {...props}>
<Button onClick={() => model.toggleCanExecute()}>
Toggle Can Execute
</Button>
</LayoutElement>
);
};
export default CustomComponent;
import {
ComponentModelBase,
serializable,
} from "@vertigis/web/models";
import { command } from "@vertigis/web/messaging";
@serializable
export default class CustomModel extends ComponentModelBase {
private _canExecuteValue: boolean = false;
@command("custom.command-with-can-execute")
protected _commandWithCanExecute(): void {
this.messages.commands.ui.alert.execute({
message: "Executed `custom.command-with-can-execute`",
});
}
toggleCanExecute(): void {
this._canExecuteValue = !this._canExecuteValue;
}
}
Implement the canExecute
Function
Finally, we need to implement the canExecute
method for the custom.command-with-can-execute
command. This method should be decorated with @canExecute
and return a boolean indicating whether the command can execute.
If the command takes an argument, the @canExecute
method will also be passed that argument.
- Component Model
- UI - Command Disabled
- UI - Command Enabled
import {
ComponentModelBase,
serializable,
} from "@vertigis/web/models";
import { command, canExecute } from "@vertigis/web/messaging";
@serializable
export default class CustomModel extends ComponentModelBase {
private _canExecuteValue: boolean = false;
@command("custom.command-with-can-execute")
protected _commandWithCanExecute(): void {
this.messages.commands.ui.alert.execute({
message: "Executed `custom.command-with-can-execute`",
});
}
@canExecute("custom.command-with-can-execute")
protected _canExecuteImplementation_(): boolean {
return this._canExecuteValue;
}
toggleCanExecute(): void {
this._canExecuteValue = !this._canExecuteValue;
this.messages
.command("custom.command-with-can-execute")
.canExecuteChanged.publish();
}
}
Live Sample
Check out a live SDK sample of a command that has a canExecute
hook.
Next Steps
Commands and Operations in Services
Learn more about commands and operations in services
Custom Services
Learn more about custom services