Skip to content

Triggers

Byron Murgatroyd edited this page Sep 14, 2018 · 2 revisions

With MooseJS we can define triggers to be called after a property is modified.

Triggers can be used as property setters or to notify of change.

The triggers will always be passed the following variables: (wholeObject, newValue, oldValue, propertyName)

class NamedThing extends MooseJS.defineClass({
    final: true,
    has: {
        name: { is:"rw", isa:String, required:true, trigger:(o) => o.onnamechange() },
        onnamechange: { is:"rw", isa:Function, required:true, default:() => { /* Do nothing */ }}
    }
})
{}

const foo = new NamedThing({ name:"foo" });

foo.onnamechange = (newName) => { console.log("name set to:", newName) }

foo.name = "bar" // Trigger fired.

We can also use triggers to validate objects. The trigger is passed the object AFTER the change but when a trigger throws an exception the variable will be re-set to it's original value.

function checkTimes(obj){
    if (obj.start >= obj.end)
        throw Error("Start time is greater than end time for appointment "+ obj.name);
}

class Appointment extends MooseJS.defineClass({
    final: true,
    strict: true,
    has: {
        name:  { is:"rw", isa:String, required:true },
        start: { is:"rw", isa:Date,   required:true, trigger:checkTimes},
        end:   { is:"rw", isa:Date,   required:true, trigger:checkTimes},
    }
})
{}


const dentistAppointment = new Appointment({
    name:  "Dentist",
    start: new Date('2018-09-09 12:00:00'),
    end:   new Date('2018-09-09 13:00:00')
})

try {
    dentistAppointment.start = '2018-09-09 14:00:00'
} catch (e){
    console.log("Error thrown as expected")
}

console.log(dentistAppointment.start) // start has reverted to '2018-09-09 12:00:00'

We could also revert the value without throwing an exception.

function checkTimes(obj, newValue, oldValue, prop){
    if (obj.start >= obj.end)
        obj[prop] = oldValue // Just revert and pretend that nothing happened.
}
Clone this wiki locally