Using the browser's
Document Object Model (DOM),
events can be attached to HTML elements by providing an attribute of the event name
prefixed with @
. For example <div @click='c.HandleClick()'>
The name of the event correspoonds to a regular DOM event as would be provided to addEventListener.
The Go expression provided may be a Go method call or other statement(s).
<div> <div vg-if='c.Show'>I am here!</div> <button @click='c.Toggle()'>Toggle me Silly</button> </div> <script type="application/x-go"> func (c *Root) Toggle() { c.Show = !c.Show } type Root struct { Show bool `vugu:"data"` } </script>
You can also place statements directly in the event tag, like so:
<div> <div vg-if='c.Show'>I am here!</div> <button @click='c.Show = !c.Show; log.Print("toggled!")'> Toggle me, Silly </button> </div> <script type="application/x-go"> import "log" type Root struct { Show bool `vugu:"data"` } </script>
-
The special variable
event
(of type vugu.DOMEvent) corresponds to the event data sent to us by the browser. It also provides some useful functionality such as aPreventDefault()
method which corresponds to preventDefault -
For operations that involve blocking (waiting for I/O, such as fetching data from a URL),
you should create a goroutine and use
event.EventEnv() to acquire
a lock before modifying data, and release it afterward.
However the lock should only be held during the variable assignment, not while blocking.
Important
When your event handler method is called, an exclusive lock is already acquired against the rendering environment. It is released automatically when your handler method exits. Do not block waiting for I/O inside your handler directly, instead use a goroutine. Inside the goroutine (and only inside goroutines, not directly in your handler method) you must use
event.EventEnv().Lock()
andevent.EventEnv().UnlockRender()
(orUnlockOnly()
) to ensure only one thing is accessing your information at a time. You can also useRLock()
andRUnlock()
for read-only access from a goroutine. These methods behave exactly as you would expect from RWMutex (and if you have never used one of those, now would be a great time to bone up on them).
Event Summary
DOMEvent
has an "event summary", which is basically a blob of JSON collected in JS when the event is fired and marshalled over to Go so you can use it and get, for example, a form value without having to reach back into JS and ask for it. The EventSummary itself is a map[string]interface{}
populated by json.Unmarshal,
but the Prop
method is useful for extracting data from it, i.e. event.Prop("target", "value")
gives you the same value as event.target.value
would in JS (and won't panic if it is not there). Variations for different types exist also, e.g. event.PropString("target", "value")
returns a string. See the
godoc for more info.
<div><form> <input type="text" @change="c.HandleChange(event)"> </form></div> <script type="application/x-go"> import "log" func (c *Root) HandleChange(event vugu.DOMEvent) { log.Print(event.PropString("target", "value")) } </script>