Skip to content

Event Handler scope

Compare
Choose a tag to compare
@maxence-charriere maxence-charriere released this 19 Feb 12:06
· 283 commits to master since this release

A scope can be added to event handler in order to trigger event handler updates.

In a scenario where we want to remove a element from a list, a solution is to create an EventHandler which got the element id set outside.
The event handler returned will always have the same addr, which prevent the package to define that an update should be done on the given element.

To solve this, a scope has been added to the methods that set EventHandler.
Here is the an example:

type issue499Data struct {
	ID    int
	Value string
}

type issue499 struct {
	app.Compo

	data []issue499Data
}

func newIssue499Data() *issue499 {
	return &issue499{}
}

func (c *issue499) OnMount(app.Context) {
	c.data = []issue499Data{
		{11, "one"},
		{22, "two"},
		{33, "three"},
		{44, "four"},
		{55, "five"},
		{66, "six"},
		{77, "sever"},
		{88, "eight"},
		{99, "nine"},
	}
	c.Update()
}

func (c *issue499) Render() app.UI {
	return app.Div().Body(
		app.H1().Text("Issue 499"),
		app.Div().
			Body(
				app.Range(c.data).Slice(func(i int) app.UI {
					d := c.data[i]
					return app.Button().
						ID(fmt.Sprintf("elem-%v", d.ID)).
						OnClick(c.newListener(d.ID), d.ID). // HERE the element ID is added in order to trigger the handler update since the func pointer returned by newListener is always the same.
						Text(d.Value)
				}),
			),
	)
}

func (c *issue499) newListener(id int) app.EventHandler {
	return func(app.Context, app.Event) {
		for i, d := range c.data {
			if id == d.ID {
				c.data = append(c.data[:i], c.data[i+1:]...)
				c.Update()
				return
			}
		}
	}
}