Re: Vue GWT: Vue.JS integration for GWT 2.8

2017-09-11 Thread Adrien Baron
Hi!

We have released the first beta version of Vue GWT. It supports almost all 
Vue.js features, and integrates with Java:

   - HTML template, with *2-way data binding*
   - Template expressions *type checking* at compile time
   - Use *regular* *Java Objects and Collections* in your templates
   - Support *injection* in Components
   - Integrates with GWT Resources and Widgets
   - HTML templates are compiled to JavaScript during Java Compilation 
   (only requires Vue.js runtime)
   - Supports most of Vue.js features
   - Supports Vue Router integration with Vue Router GWT 
   

Feel free to take a look:
https://github.com/Axellience/vue-gwt

Regards,
Adrien.

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.


Re: Vue GWT: Vue.JS integration for GWT 2.8

2017-01-09 Thread Adrien Baron


> I'm no longer sure that would work. Even if I prefix my "to-go-in-data {}" 
> fields in the Java class with $ so as to signal VueGwt to only put these 
> properties in data {}, Vue monitors the properties defined in data {} 
> *recursively. *So if I have a field which is OK to go in data {} but the 
> object kept inside this field *itself *has fields which should not be 
> monitored by Vue, there is no way to tell Vue not to do so... Just look at 
> Vue's state.js & observer.js code...
>

Indeed the Data model is watched recursively. But this is not too much of 
an issue in my opinion as long as you don't have recursion in the objects 
you use in your data model. The way Vue.JS watch data model is by using 
native JS getter/setter overrides, so if you don't use a property there is 
not much performance cost (except setting those getter/setter).

I think the "return JSON.parse(JSON.stringify(data));" trick that you do in 
> VueGwtTools.js has to go. 
> For one, this call completely disconnects the original set of fields in 
> data {}, from the ones that Vue will monitor. So I'm not sure that the 
> current VueGwt implementation monitors the correct fields at all?
>
> Also, a copy of the data {} is anyway required in Vue.js only when you 
> register a new Vue *component* (as opposed to just instantiating a new 
> Vue instance): 
> https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
> Perhaps the misunderstanding and the mismatch comes from how you register 
> a new component. In  your example, you do it like this:
>
> @JsTypepublic class RootComponent extends VueComponent
> {
> public RootComponent()
> {
> // ChildComponent is registered to be used in our RootComponent
> this.registerComponent(new ChildComponent());
> }
> }
>
>
> In Java and also with your approach where data {}, props {} methods {} and 
> all are flattened in a single Java object, it would feel much more natural 
> if you do it like this:
>
> @JsTypepublic class RootComponent extends VueComponent
> {
> public RootComponent()
> {
> // ChildComponent is registered to be used in our RootComponent
> this.registerComponent(ChildComponent.class);
> }
> }
>
>
> ... and then VueGwt should map a JS *function *to the Vue "data" property 
> which function should instantiate a fresh instance of the ChildComponent 
> class, ending up with a separate data {} copy for each new component 
> instance, as is required.
> (It is another topic how to do this reflective instantiation of the 
> component with GWT anyway. Perhaps you need a Factory pattern here, in the 
> absence of reflection in GWT?)
>
>
For the JSON.stringify call, as you said it disconnects the properties from 
the actual instance. We could provide two choice (common data model for all 
components instance, or a factory to get an instance of data model for each 
component). But no matter what the data properties will get disconnected 
from the component instance you create to register it.

It is because the Java "Components" are not so much components and more 
templates for Vue.JS. For example their constructor is never called when a 
new Component is constructed, only once when registered. So indeed the 
properties you manipulate on the Java side are not the one you end up 
manipulating in your JS component.

It's similar to what happens with regular Vue.JS. You usually declare your 
"data" object (or function returning new instance of data) and next to it 
the methods.
If in your data you have a property "hello", in your component methods you 
do "this.hello", but the "this" at the moment of declaration is going to be 
your component instance with it's own data when your component will be 
instantiated.

So in the Java Component, the "this.hello" you do, even though in the Java 
code it references the hello attribute of your Component class, at runtime 
it won't be, it will just be a hello attribute on a Vue instance created by 
Vue.

So I totally agree with you when you say it would feel way more natural to 
pass the Class to register the component. This will be how it works if we 
use Annotations (because as you said, we can't create instance on the fly 
with GWT :(). Components could even be abstract, to show that they should 
not be instantiated directly.

 

> That would be nice. I have no experience with annotation processors 
> myself, unfortunately. I think Angular2-Gwt uses this approach, isn't it? 
> Perhaps you can contact the Angular2-Gwt maintainer for further info on the 
> subject.
>
> But then: even with that approach you have the "recursion" problem I 
> mentioned at the top of my reply (Vue.js traversing all properties in data 
> {} recursively), isn't it?
>

Yes it's indeed how they do it. I'll make sure to ask them some advice :).
And yes we would still get the recursivity issue. It would indeed be a 
limitation compared to what you can do in Java (meaning not being able to 
have recursive data st

Re: Vue GWT: Vue.JS integration for GWT 2.8

2017-01-09 Thread Ivan Markov

>
>
> => Java to JS component translation
>
> Indeed the Java introspection at runtime is also not my favorite thing. 
> Adding a $ before each property name could be a valid solution and I'm 
> surely considering it :).
> This will also negate the need to filter out properties manually (like the 
> ___ that is too generic), because only the "interesting" properties would 
> be copied over.
>

I'm no longer sure that would work. Even if I prefix my "to-go-in-data {}" 
fields in the Java class with $ so as to signal VueGwt to only put these 
properties in data {}, Vue monitors the properties defined in data {} 
*recursively. *So if I have a field which is OK to go in data {} but the 
object kept inside this field *itself *has fields which should not be 
monitored by Vue, there is no way to tell Vue not to do so... Just look at 
Vue's state.js & observer.js code...
 

>
> For the @JsProperty, sadly they still would need it (or at least a @JsType 
> + public properties), as the Vue.JS template are not parsed by GWT. The 
> name in the template must match the ones in the JS translation of the Java 
> component. If GWT rename them at compile time, then you'll get for example:
> {{ bob }} in your template and data: {a: "hello"} in your component.
>

That's correct.

 

>
> => Circular reference in data model.
>
> I tried to create in pure Vue.JS a component that returns a circular 
> reference upon creation, and it also breaks:
> https://codepen.io/anon/pen/oBXBmB
> (if you remove the test.circular = test, it works again).
>
> Also Vue doc in v1 specifically said that it needs not not contain 
> circular reference. In the v2 they say that you can clone the data using 
> JSON.stringify(JSON.parse(...));
> https://github.com/vuejs/Discussion/issues/265
> https://vuejs.org/v2/api/#data
>
> Fixing the way we build the Component data to make sure to only integrate 
> the properties needed by the user would probably make this less of an issue.
>

I think the "return JSON.parse(JSON.stringify(data));" trick that you do in 
VueGwtTools.js has to go. 
For one, this call completely disconnects the original set of fields in 
data {}, from the ones that Vue will monitor. So I'm not sure that the 
current VueGwt implementation monitors the correct fields at all?

Also, a copy of the data {} is anyway required in Vue.js only when you 
register a new Vue *component* (as opposed to just instantiating a new Vue 
instance): https://vuejs.org/v2/guide/components.html#data-Must-Be-a-Function
Perhaps the misunderstanding and the mismatch comes from how you register a 
new component. In  your example, you do it like this:

@JsTypepublic class RootComponent extends VueComponent
{
public RootComponent()
{
// ChildComponent is registered to be used in our RootComponent
this.registerComponent(new ChildComponent());
}
}


In Java and also with your approach where data {}, props {} methods {} and 
all are flattened in a single Java object, it would feel much more natural 
if you do it like this:

@JsTypepublic class RootComponent extends VueComponent
{
public RootComponent()
{
// ChildComponent is registered to be used in our RootComponent
this.registerComponent(ChildComponent.class);
}
}


... and then VueGwt should map a JS *function *to the Vue "data" property 
which function should instantiate a fresh instance of the ChildComponent 
class, ending up with a separate data {} copy for each new component 
instance, as is required.
(It is another topic how to do this reflective instantiation of the 
component with GWT anyway. Perhaps you need a Factory pattern here, in the 
absence of reflection in GWT?)

 

>
> => Minor issues
>
> 1: Yes, for now we just wanted to get feedback, so it wasn't needed, but 
> if people show interest it will happen.
>
> 2: Indeed, nice catch! I'll make sure to add it to the documentation.
>
>
> => Other questions
>
> As you saw even if the Java introspection is nice and pretty easy to do 
> (with naming convention), it doesn't not feel very "Java" or clean to code 
> with it. I was thinking about using annotations with annotations processor 
> to avoid having naming conventions.
>
> For example a simple component could look like:
> @Component
> public class myComponent extends VueComponent {
>   @VueData
>   protected String myMessage = "Hello";
>
>   @VueMethod
>   protected void resetMessage() {
> this.myMessage = "";
>   }
>
>   @VueWatch
>   protected void myMessage() {
> // Do something
>   }
> }
>
> This would be much cleaner to code. Also it might be possible to 
> automatically bind templates, we would also gain the ability to fine tune 
> the component behavior by passing parameters to the @Component annotation.
>
> My main issue with this is after doing some research, it seems that 
> annotation processors integrates poorly for now with GWT super dev mode. 
> You have to manually rereun the annotation processor after each change. I 
> do

Re: Vue GWT: Vue.JS integration for GWT 2.8

2017-01-06 Thread Adrien Baron
Hi!

Thank you for this detailed reply! I'm very glad that you took the time to 
look into the code and you are indeed raising interesting issues.

I'll try to reply to each remarks:

=> Java to JS component translation

Indeed the Java introspection at runtime is also not my favorite thing. 
Adding a $ before each property name could be a valid solution and I'm 
surely considering it :).
This will also negate the need to filter out properties manually (like the 
___ that is too generic), because only the "interesting" properties would 
be copied over.

For the @JsProperty, sadly they still would need it (or at least a @JsType 
+ public properties), as the Vue.JS template are not parsed by GWT. The 
name in the template must match the ones in the JS translation of the Java 
component. If GWT rename them at compile time, then you'll get for example:
{{ bob }} in your template and data: {a: "hello"} in your component.

=> Circular reference in data model.

I tried to create in pure Vue.JS a component that returns a circular 
reference upon creation, and it also breaks:
https://codepen.io/anon/pen/oBXBmB
(if you remove the test.circular = test, it works again).

Also Vue doc in v1 specifically said that it needs not not contain circular 
reference. In the v2 they say that you can clone the data using 
JSON.stringify(JSON.parse(...));
https://github.com/vuejs/Discussion/issues/265
https://vuejs.org/v2/api/#data

Fixing the way we build the Component data to make sure to only integrate 
the properties needed by the user would probably make this less of an issue.

=> Minor issues

1: Yes, for now we just wanted to get feedback, so it wasn't needed, but if 
people show interest it will happen.

2: Indeed, nice catch! I'll make sure to add it to the documentation.


=> Other questions

As you saw even if the Java introspection is nice and pretty easy to do 
(with naming convention), it doesn't not feel very "Java" or clean to code 
with it. I was thinking about using annotations with annotations processor 
to avoid having naming conventions.

For example a simple component could look like:
@Component
public class myComponent extends VueComponent {
  @VueData
  protected String myMessage = "Hello";

  @VueMethod
  protected void resetMessage() {
this.myMessage = "";
  }

  @VueWatch
  protected void myMessage() {
// Do something
  }
}

This would be much cleaner to code. Also it might be possible to 
automatically bind templates, we would also gain the ability to fine tune 
the component behavior by passing parameters to the @Component annotation.

My main issue with this is after doing some research, it seems that 
annotation processors integrates poorly for now with GWT super dev mode. 
You have to manually rereun the annotation processor after each change. I 
do think the code would look nice with annotations, but if developing with 
it becomes slow and cumbersome, then there is not really a point.

I wonder what you think of this idea, and if you have any experience with 
annotation processor in GWT ?


Anyway, thank you very much for your feedback!


On Friday, January 6, 2017 at 7:27:29 PM UTC+1, Ivan Markov wrote:
>
> Hi there.
>  
>
>> It's still a work in progress, but* we would be glad to hear what you 
>> think of it.*
>>
>>
> What I think is the following: this is very neat! 
>
> With the above said, I have one roadblocker and two minor issues 
> (disclaimer: I'm a *complete* NB in Vue.js).
>
> The roadblocker:
> ==
>
> You are converting the Java/GWT representation of a Vue component into the 
> one Vue expects by using a runtime introspection of the VueComponent object 
> from within JavaScript.
> Because of this approach, you are putting properties in data {} which are 
> NOT declared as a @JsProperty in Java. You know, internal private members 
> that I might have in my Vue component ending on _g$, like an EventBus 
> instance or you-name-it.
> The problem with this is that the conversion fails in JSON.parse() with a 
> "Converting circular structure to JSON" complaint.
>
> Given that it is not very realistic - especially in hybrid Vue/GWT Widget 
> projects to have all props marked as @JsProperty, and all of these to be 
> non-circular, this probably needs to be addressed.
>
> An idea: since you are anyway using naming conventions (a computed_ prefix 
> for computed props, a watch_ prefix for watchers), how about applying this 
> to ALL props that should end in data {} and perhaps to all methods that 
> should end in methods {}?
> Perhaps you can fix it so that it processes only methods and properties 
> that are starting with e.g. a single "$" or suchlike?
> NOTE: That might have the additional benefit that these methods and 
> properties might not necessarily have to be marked with 
> @JsMethod/JsProperty, as you - in fact - don't care about their name being 
> preserved from Java to JS, as long as it starts with a "$".
>
> Another idea: you are anyway filtering out so

Re: Vue GWT: Vue.JS integration for GWT 2.8

2017-01-06 Thread Ivan Markov
Hi there.
 

> It's still a work in progress, but* we would be glad to hear what you 
> think of it.*
>
>
What I think is the following: this is very neat! 

With the above said, I have one roadblocker and two minor issues 
(disclaimer: I'm a *complete* NB in Vue.js).

The roadblocker:
==

You are converting the Java/GWT representation of a Vue component into the 
one Vue expects by using a runtime introspection of the VueComponent object 
from within JavaScript.
Because of this approach, you are putting properties in data {} which are 
NOT declared as a @JsProperty in Java. You know, internal private members 
that I might have in my Vue component ending on _g$, like an EventBus 
instance or you-name-it.
The problem with this is that the conversion fails in JSON.parse() with a 
"Converting circular structure to JSON" complaint.

Given that it is not very realistic - especially in hybrid Vue/GWT Widget 
projects to have all props marked as @JsProperty, and all of these to be 
non-circular, this probably needs to be addressed.

An idea: since you are anyway using naming conventions (a computed_ prefix 
for computed props, a watch_ prefix for watchers), how about applying this 
to ALL props that should end in data {} and perhaps to all methods that 
should end in methods {}?
Perhaps you can fix it so that it processes only methods and properties 
that are starting with e.g. a single "$" or suchlike?
NOTE: That might have the additional benefit that these methods and 
properties might not necessarily have to be marked with 
@JsMethod/JsProperty, as you - in fact - don't care about their name being 
preserved from Java to JS, as long as it starts with a "$".

Another idea: you are anyway filtering out some GWT methods, like those 
starting with "$init" or with "___" (the latter might be dangerous btw as 
it is a bit too generic!), so you can just as well filter out everything 
that ends with _g$ as well, because that's the mangling suffix GWT puts on 
all props and methods which had not been exposed via @JsProperty / 
@JsMethod / @JsType annotations. Of course this relies on GWT internals and 
might break in future, but I don't think there will be a perfect, pure and 
clean solution anyway if a JS object introspection is used.

Now, even if the above is addressed (and I think it should as the 
programmer has to have control what ends up in data {} and methods {}), the 
whole "return JSON.parse(JSON.stringify(data));" approach is not giving me 
a warm fuzzy feeling. Is that how Vue is supposed to work? With 
non-circular data {} only?

Two minor issues:
=

1. Having the project published in Maven Central soon would be nice - even 
if it is just a snapshot.

2. I was missing a "https://unpkg.com/vue/dist/vue.js";>" include and it took me 
some time to realize it. If VueGwt indeed does not inject the vue.js lib, 
this has to be at least mentioned in the GitHub README.md file.


*Keep up the good work!*
 

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.


Vue GWT: Vue.JS integration for GWT 2.8

2017-01-05 Thread Adrien Baron
Hi,

We've just released an experimental version of *Vue GWT* 
. It's a Vue.JS  
integration for GWT 2.8 using JsInterop. It lets you easily create Vue.JS 
components in GWT.

For example a simple component can look like this:



Press me!

You pressed {{ counterValue }} times


@JsType
public class SimpleCounterComponent extends VueComponent
{
public int counterValue = 0;

public void increaseCounter()
{
this.counterValue++;
}
}

It's still a work in progress, but* we would be glad to hear what you think 
of it.*

You can check out the demo page built with Vue GWT here:
https://axellience.github.io/vue-gwt-demo/

You can check the project out on GitHub:
https://github.com/Axellience/vue-gwt

We've also created a Gitter for quick feedbacks:
https://gitter.im/Axellience/vue-gwt

-- 
You received this message because you are subscribed to the Google Groups "GWT 
Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to google-web-toolkit+unsubscr...@googlegroups.com.
To post to this group, send email to google-web-toolkit@googlegroups.com.
Visit this group at https://groups.google.com/group/google-web-toolkit.
For more options, visit https://groups.google.com/d/optout.