This interface provides access to the memento design pattern to provide undoability for arbitrary models.
Remarks
By implementing this interface as well as ILookup, clients can add undoability for changes to their model classes. The yFiles undo mechanism uses the return value of getState to retrieve a state of an item at the beginning of the compound editing process. When the process ends, another state will be retrieved of the same item and compared to the original state. If they differ, an IUndoUnit is created that uses the applyState method to apply either state to the item in case of undo or redo. This represents an abstraction to the undo mechanism where it is only needed to define "states" of items and hides the more complicated mechanism of creating and inserting IUndoUnits.
The following is an example implementation of an item that is being managed using IMementoSupport:
class Employee extends BaseClass<ILookup>(ILookup) implements ILookup {
_name: string
position: string
age: number
constructor(name: string, position: string, age: number) {
super()
this._name = name
this.position = position
this.age = age
}
get name(): string {
return this._name
}
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-constraint
lookup<T extends any>(type: Constructor<any>): T | null {
if (type === IMementoSupport) {
return new EmployeeMementoSupport() as T
}
return null
}
}
A collection of items from this type can then be watched using the following code snippet:
const edit = graph.beginEdit(
undoName,
redoName,
listWithMyEmployeesToWatch,
)
// changes to the employees are done here
if (!success) {
// if we don't want the changes to be done after all, then we need to cancel the edit
edit.cancel()
}
Implementing the IMementoSupport interface is quite unrestrained, the type of the state returned by getState method can by anything as long as the applyState and stateEquals methods can deal with it:
class EmployeeMementoSupport
extends BaseClass<IMementoSupport>(IMementoSupport)
implements IMementoSupport
{
getState(subject: any): EmployeeState | null {
if (subject instanceof Employee) {
return new EmployeeState(subject.position, subject.age)
}
return null
}
applyState(subject: any, state: any): void {
if (subject instanceof Employee && state instanceof EmployeeState) {
subject.position = state.position
subject.age = state.age
}
}
stateEquals(state1: any, state2: any): boolean {
if (
state1 instanceof EmployeeState &&
state2 instanceof EmployeeState
) {
return (
state1.position === state2.position && state1.age === state2.age
)
}
return state1 === state2
}
}
class EmployeeState {
_position: string
_age: number
constructor(position: string, age: number) {
this._position = position
this._age = age
}
get position(): string {
return this._position
}
get age(): number {
return this._age
}
}
In summary, use this concept when you want to track the state of items during certain operations for undo/redo. This is efficient if it's easier to handle an item's state than the changes to the item themselves. If you want to focus on the changes or on certain events, you should use custom IUndoUnit implementations instead.
Type Details
- yFiles module
- view
See Also
Methods
Retrieves an object representing the state at the moment this method is called.
Remarks
Parameters
A map of options to pass to the method.
- subject - any
- The subject to read the state from
Returns
- ↪any
- An object that describes the current state of
subject
.
Determines whether two state objects are equal.
Remarks
false
, an IUndoUnit is created for the two states that can reapply either state (for either undo or redo). If this method returns true
the state is considered not to have changed and no undo unit will be created. Conservative implementations may simply return false
.Parameters
A map of options to pass to the method.
- state1 - any
- The first state as obtained from getState
- state2 - any
- The second state as obtained from getState
Returns
- ↪boolean
true
if the states are equal;false
otherwise.
Static Methods
Parameters
A map of options to pass to the method.
- getState - function(any):any
Retrieves an object representing the state at the moment this method is called.
This property holds the implementation for getState.
- applyState - function(any, any):void
Reapplies a previously queried state object to a given subject.
This property holds the implementation for applyState.
- stateEquals - function(any, any):boolean
Determines whether two state objects are equal.
This property holds the implementation for stateEquals.