wirebase / wire

The single tool that enables the development of both static, dynamic ánd single-page web frontends from a single Go codebase.
Apache License 2.0
1 stars 0 forks source link

Could you describe how to get started with this tool? #1

Open 030 opened 5 years ago

030 commented 5 years ago

I like the idea. Could you describe in the readme how to get started? Perhaps you could add an example project?

advdv commented 5 years ago

@030 Wow, that was quick. I've only just started to put some of the effort online, but welcome! How did you find this project if I may ask?

Unfortunately, the wirebase/wire cli is currently not very useful without the Go library that goes with it. The library is still in the works and I only expect it to be online in a couple of months but maybe you're interested giving your opinion general idea? The concept is this:

So how does this enable dynamic, static and single-page apps?

Code example Your input is very valuable, so i'm curious to your impressions! I'm also located in the Netherlands so feel free to pm me.

package main

import (
    "github.com/wirebase/wb"
    "github.com/wirebase/wb/ajax"

    // this package allows for expressive declaration of HTML
    . "github.com/wirebase/wb/html"
)

// This example defines two message types, one to increment
// and one to decrement the counter.
type (
    increment struct{}
    decrement struct{}
    saved     struct{}
)

// Counter component has a very simple state, just a number
// to keep track of.
type Counter struct{ i int }

// NewCounter should initialize the component, in this case
// we start counting at 1
func NewCounter() *Counter {
    return &Counter{i: 1}
}

// Update is called whenever an event is available for the
// application to handle. This event might come from a Cmd
// that was scheduled or an user interaction. Optionally, a
// command can be returned that will be executed after
// Rendering (e.g a Ajax request).
func (c *Counter) Update(m wb.Msg) wg.Cmd {
    switch msg := m.(type) {
    case increment:
        c.i++
    case decrement:
        c.i--
    case saved:
        c.i = 0 //reset if saved
    }

    // lets imagine that we want to send an ajax request
    // if someone manages to increment it to 10. The ajax
    // request is send asyncronously by the runtime and
    /// sends 'saved' message back to the application when
    // its done.
    if c.i >= 10 {
        return ajax.NewRequest("post", "http://localhost/save_count", saved{})
    }

    return nil
}

// Render returns a declarative representation of the DOM
// that visually represents this component. The runtime
// will take care of removing and adding the necessary
// elements to present it to the user correctly. We use 
// dot imports here to make defining the html more 
// expressive.
func (c Counter) Render() wb.View {
    return Div(C{"id": "my-counter"}
        Button(c{"id": "inc"}),
        Span(c.i), //show the currently counting method
        Button(c{"id": "dec"}),
    )
}

// Subscribe may define a set of subscriptions that will
// cause the sending of messages to the application. Subscribe
// is called after render and after execution of any
// commands. It may subcribe differently based on the 
// component state.
func (c Counter) Subscribe() wb.Sub {
    return wb.MultiSub(

        // we use jqery like syntax to target elements in 
        // our view and declare listeners. Upon clicking
        // the respective button the `inc` or `dec` message 
        // will be send to the update method. 
        wb.Listen("#inc", "onclick", inc{})
        wb.Listen("#dec", "onclick", dec{})
    )
}
030 commented 5 years ago

@advanderveer Regarding:

How did you find this project if I may ask?

I am following you on Github.

advdv commented 5 years ago

Cool! What do you think of the concept?