go-humble / view

A small go library for managing views in the browser which compiles to javascript via gopherjs.
MIT License
7 stars 1 forks source link

Add support for events #1

Open albrow opened 9 years ago

albrow commented 9 years ago

I think we'll take inspiration from backbone here, since they also have template language agnostic views. What I'm thinking right now is that there will be a way to specify events for each view. Possibly via an Events method and Event type.

type Event struct {
    Name     string
    Selector string
    Handler  func(dom.Event)
}

The view package can then check if you have implemented the Events method with an type assertion.

type Eventer interface {
    View
    Event() []Event
}

Finally there could be a DelegateEvents helper function which takes an Eventer as an argument.

func DelegateEvents(eventer Eventer) {
    // Iterate through the events in eventer.Events() and attach them to eventer.Element() 
}

Here's an example of how you might add events to a TodoView:

type TodoView struct {
    Todo *models.Todo
    view.DefaultView
}

func (v TodoView) Events() []view.Event {
    return []Event{
        {
            Name: "click",
            Selector: ".toggle",
            Handler: func(dom.Event) {
                v.Todo.ToggleCompleted
            },
        },
        {
            Name: "click",
            Selector: ".destroy",
            Handler: func(dom.Event) {
                v.Remove()
            },
        },
    }
}

The advantage to this approach is that the Events method is tied to a View type declaration, and not to a specific View instance. This is the behavior that is more commonly wanted.

Depending on how this all feels, I may split events into their own package and import the event package into the view package for delegating events to views.

fabioberger commented 9 years ago

Thanks for submitting this for feedback. The structure of the events struct looks good, as well as the interface setup.

Clarification: Would the Events() method be used to declare the events a view should have onload? What if we want to add or remove events based on user interactions with the view?

albrow commented 9 years ago

@fabioberger thanks for your comments. Yeah the Events method is for declaring events the view should have on load. If you want to add or remove events manually, it's not hard to do it with the dom package. It would look something like

view.Element().AddEventListener("click", true, func(event dom.Event){
    // Do something with event
}) 

I might add some utilities for adding and removing events since currently the RemoveEventListener function requires a js.Object as an argument. It's a little weird and not go-like. If I add this it's just going to be a really lightweight wrapper.

Thinking I'm most definitely going to create a separate event package, so keep an eye out for that!

fabioberger commented 9 years ago

Awesome, then this proposal looks great, I'll be excited to use it in production. Its a much cleaner, pragmatic approach then my current solution. Great work!