Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Can't find a elegant way to define a multi instanciated component #10

Open
lpuigo opened this issue Sep 24, 2017 · 1 comment
Open

Can't find a elegant way to define a multi instanciated component #10

lpuigo opened this issue Sep 24, 2017 · 1 comment

Comments

@lpuigo
Copy link

lpuigo commented Sep 24, 2017

Hi Oskca,

First of all, many thanks for this very nice and convenient GopherJS extension on VueJS.

I'm struggling with proper Component definition in order to define a component wich can be instanciated many time within a html page

I've finally wrote this working code :

const (
	TemplateCounter = `
	<div class="ui labeled button" tabindex="0" @click="Inc">
		<div class="ui button" :class="color">
			<i class="heart icon"></i> Like
		</div>
		<a class="ui basic left pointing label" :class="color">{{cnt}}</a>
	</div>
`
)

// CounterComp GopherJs Code
type CounterComp struct {
	*js.Object
	Cnt int `js:"cnt"`
}

func NewCounterComp() *CounterComp {
	cc := &CounterComp{
		Object: js.Global.Get("Object").New(),
	}
	cc.Cnt = 0
	return cc
}

func (cc *CounterComp) Inc() {
	cc.Cnt++
}


// RegisterCompteurComp registers to current vue intance a counter component having the following profile
//  <counter color="some_color_name"></counter>
func RegisterCompteurComp() *vue.Component {
	o := vue.NewOption()
	o.Template = TemplateCounter

	//o.Data = func() interface{} {
	//	return NewCounterComp()
	//}
	// which is equivalent to following
	//o.Set("data", NewCounterComp)
	// and also equivalent to following (kept because shorter)
	o.Data = NewCounterComp

	o.AddMethod("Inc", func(vm *vue.ViewModel, args []*js.Object) {
		vm.Data.Set("cnt", vm.Data.Get("cnt").Int()+1)
	})

	o.AddProp("color")

	return o.NewComponent().Register("counter")
}

This code works ok (it enables multiple counter component intances to work side to side, with a specific value in each occurence), but It does not please me :

As o.SetDataWithMethods(NewMessageComp) ( nor o.SetDataWithMethods(NewMessageComp())) does not seem to work in this case (method "Inc" is not defined on JS side), is there a way to use the actual method assocatied with the Go type, instead of having to "rewrite" the logic in a (Gopher)JS way ?

As a turn around, I used the o.AddMethod... stuff, but it is frustrating for me as it does not reuse the func (cc *CounterComp) Inc() method from CounterComp Go type.

Any hint (or even better, a more comprehensive exemple for component) would be really appreciated

Best Regards
Laurent

@lpuigo
Copy link
Author

lpuigo commented Sep 30, 2017

Having a second look at GopherJS wiki (https://github.com/gopherjs/gopherjs/wiki/JavaScript-Tips-and-Gotchas#tips), I found out kind of a solution :

Here is the reworked version of func RegisterCounterComp :

// RegisterCounterComp registers to current vue intance a counter component having the following profile
//  <counter color="some_color_name"></counter>
func RegisterCounterComp() *vue.Component {
	o := vue.NewOption()
	o.Template = TemplateCounter
	o.Data = NewCounterComp

	o.AddMethod("Inc", func(vm *vue.ViewModel, args []*js.Object) {
		(&CounterComp{Object:vm.Data}).Inc()
	})

	o.AddProp("color")

	return o.NewComponent().Register("counter")
}

This doesn't map directly the exported method of Go Type CounterComp, but at least it enables to reuse the Inc() method.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant