Can I use enum values as field values inside UiBinder template ? I'm using GWT 2.4
Something like this
<ui:with field="en" type="com.mine.courierApp.shared.PayerType" />
looks promising, where
public enum PayerType
{
Sender,
Recipient
}
but I can't refer to values of the enum by en.Sender.
Is it even possible ?
<ui:import field='com.mine.courierApp.shared.PayerType.Sender' />
or
<ui:import field='com.mine.courierApp.shared.PayerType.*' />
And then you can use it as payerType='{Sender}'.
But UiBinder should automatically try to translate enum constant names into values, so the following should work without any need for a ui:with:
<my:MyWidget payerType='Sender' />
If the MyWidget widget has a public void setPayerType(PayerType type) method, UiBinder should look for an enum value named Sender (from the *.ui.xml file) in the PayerType enum (from the method's argument type).
If you don't ui:import the enum class like this:
<ui:import field='com.mine.courierApp.shared.PayerType.*' />
then you don't get content-assist, which the whole point of this in the first place.
But then you run into another issue...
Although you can simple type { ctrl-space } to get a popup menu of the enum value, if you are using, say, bootstrap3, there are various enums that each have their own "DEFAULT" value. The ui template editor will complain about that; i.e. if you start making extensive use of this content-assist feature, you will need to ensure the imported enums have unique value names.
Related
I am creating a custom widget, say "CustomWid" in UiBinder.
And in CustomWid.java file I am writing two constructors
one with zero args like
CustomWid(){....}
another with some args like
CustomWid(String a,String b){......}
So,Now I am using my custom widget in another .ui.xml file,in that .ui.xml file
it is working fine when we give
<my:CustomWid/> alone,
and also fine when we give like
<my:CustomWid a="srt1" b="str2"/> alone
But "MY PROBLEM" is whenever I am trying to give both the tags in the one .ui.xml as
<my:CustomWid/>
<my:CustomWid a="str1" b="str2"/>
Now it is throwing error when i am using both types of tags in a single .ui.xml
I mean How to use my custom widget tag like a prdefined tag?
I am using #uiConstructor, but it showing error
Please developers... I need answer as early as possible
UiBinder will only ever use a single constructor for a given widget: either its zero-arg constructor, or a #UiConstructor (I'm surprised that you say it works when using either one or the other call but not both: one should fail in every case, and one should succeed in every case; if you haven't annotated a constructor with #UiConstructor, then <my:CustomWid/> should always work and <my:CustomWid a="str1" b="str2"/> should always fail)
There are two solutions here:
use setters for the a and b attributes (void setA(String a) and void setB(String b))), and possibly check later (say, in onLoad or onAttach) that you have either none or both of A and B, but not one without the other (if that's your rule).
use #UiField(provided = true) when you need to use the other constructor (if you choose to have UiBinder use the zero-arg constructor –i.e. no #UiConstructor–, then that means you'll have to move the a="str1" b="str2" from the XML to the Java code: #UiField(provided = true) CustomWid myCustomWid = new CustomWid("str1", "str2")).
The first option has my preference.
It Will not show any errors...'
#UiConstructor
public Component(String displayText,String heading)
{
initWidget(uiBinder.createAndBindUi(this));
this.displayText.setText(displayText);
this.heading.setText(heading);
}`
now use another constructor with default parameters also it will work
public Component()
{
initWidget(uiBinder.createAndBindUi(this));
}
now if you add with xml parameters component and without parameters also works in the same page.
I have the following situation. There are two combos on my UI form, one shows the list of vegetables and another one shows a list of fruits.
In my supporting view class I'd like to declare such methods:
#UiFactory
SimpleComboBox<Vegetable> createVegetablesCombo() {
return vegetables;
}
#UiFactory
SimpleComboBox<Fruit> createFruitsCombo() {
return fruits;
}
But it seems that GWT does not recognize parameterized returned types... Every time I get an error:
ERROR: Duplicate factory in class VegetablesAndFruitsView for type SimpleComboBox.
Is it possible to handle this case? Is there a good example of multiple comboboxes on one UI form?
From the perspective of Java (not GWT, not UiBinder, but the Java language itself) at runtime there isn't a difference between SimpleComboBox<Vegetable> and SimpleComboBox<Fruit>. That said, this error is coming from UiBinder's code generation, which is looking for all #UiConstructor methods, and using them to build things.
So what does UiBinder have to work with? From the UiBinder XML, there is no generics. The only way UiBinder could get this right is if you happen to have included a #UiField entry in your class with the proper generics. This then would require #UiField annotations any time there might be ambiguity like this, something GWT doesn't presently do.
What are you trying to achieve in this? You are returning a field (either vegetables or fruits) - why isn't that field just tagged as #UiField(provided=true)? Then, whatever wiring you are doing to assign those fields can be used from UiBinder without the need for the #UiConstructor methods at all.
#UiField(provided=true)
SimpleComboBox<Fruit> fruits;
//...
public MyWidget() {
fruits = new SimpleComboBox<Fruit>(...);
binder.createAndBind(this);
}
...
<form:SimpleComboBox ui:field="fruits" />
If this is just an over-simplification, and you actually plan on creating new objects in those methods, then consider passing an argument in, something like String type, and returning a different SimpleComboBox<?> based on the value. From your UiBinder xml, you could create the right thing like this:
<field:SimpleComboBox type="fruit" />
Are there any recommended structural design patterns for MVVM view models that allow different state and functionality to be added to a base object dynamically, but still maintaining the INotifyPropertyChanged on all the related properties? Something like a decorator pattern but mvvm-ready?
Yes. The WPF binding system will use a custom type descriptor to interact with the properties of your ViewModel at runtime. I've used this before to make keys in a KeyValueCollection<T> appear as properties on the collection.
This has two important benefits. It simplifies binding:
DataContext.SomeCollectionProperty[SomeKey] can be simplified to DataContext.SomeCollectionProperty.SomeKey and, if you make a custom type descriptor for the data context, DataContext.SomeKey which is about as simple as it gets.
And it fixes what I consider a bug--format strings are rendered even when the property is null. Using a CTD, you can skip null (and DBNull) properties, ensuring that format strings won't be rendered if the property doesn't exist:
Imagine you have a double? that you must render as a dollar amount. If you use the following binding: {Binding Price, FormatString='Price: {0:c}'} and the Price is null, you get the following in your UI: Price: $. This is ugly. However, if Price is a PropertyDescriptor-based property on your UI, when the Price is null, you can opt to not to report this property via your CTD. This prevents the format string from being rendered at all.
Here's a pretty good link at MSDN about decorating your types with a CTD.
From my experimentation, you can use the ExpandoObject in .NET 4 to handle what you want. ExpandoObject implements INPC. I've been creating a DynamicViewModel based on the ExpandoObject that does a few other things like calculated Properties that have dependencies on each other and Delegate Command registration.
HtmlHelpers are really useful, also i was using AjaxHelpers untill i wanted to do something they can't... so now i'm prefering jquery+javascript, but i don't like to write in javascript (mayby because i never know it as good as i wanted) and to make life easier i wanted to implement something like JQueryHelper, but right now i don't know how
I wanted to use inside of "Helper" resolved URL's, because most methods would just pass data to controllers etc... and update some parts of UI, so i'd like to create something like AjaxHelper, but based on JQuery, not MSScripts.
What should I include in such class? how can i get context, url's and generate proper javascript code which can by dynamicly injected into
ex.
<div onclick=JQuery.Action("<ActionName>", "<Controller>", new { param1, param2}, <Id to Update>)> My Div</div>
How is it implemented in HtmlHelper or AjaxHelper?
Edit:
I've tried few simple implementation, but i think I'm lack of knowledge and don't know how to implement class with extensions exacly.
I've ClassA(class) and ClassAExt(extensions):
I've something like that:
static public class ClassAExt{
public static MvcHtmlString Method(this ClassA classA) {
}
}
But in View(), when I'm using ClassAExt.Method() i have to pass also instance of ClassA (in helpers Ajax and Html this argument is grey (optional? not needed?), how to get such effect).
I am not sure if I understand your question correctly.
The HtmlHelper also get instantiated (i.e. new HtmlHelper()) during the course of page rendering and user control rendering. Ajax and URL helpers also get instantiated and this is what give one access to the various variables such HttpContext etc.
So in order for you to use your helper class related to ClassA you too will need to instantiate it. I think then the question leads to how do I do this? You will probably need to extend the ViewPage, ViewUserControl and ViewMasterPage classes.
Its non obvious because its so obvious. Basically, you extend html helper's extension:
public static HtmlString Foo(this HtmlHelper helper, string param)
{
//do whatever
}
You can get at request context, etc, from HtmlHelper.
Way I see it, you problem is that you don't understand extension methods.
if you have
static public class ClassAExt{
public static MvcHtmlString Method(this ClassA classA) {
}
}
you use it in view like this:
<%: ClassAInstance.Method() %>
to do that, you have to add <add namespace="NamespaceOfClassA" /> to you web.config's pages/namespaces section.
This way, you can extend the HtmlHelper class to do whatever you need, so there is really nothing it can't do. If you want it to do something it can't by default, just write an extension method. Also download MVC Futures assembly, there's a dll Microsoft.Web.Mvc that contains (among other things) a lot of useful extension methods for HtmlHelper.
If you want to know how they implemented HtmlHelper or AjaxHelper you can check out MVC source code.
Link to download both MVC Futures and MVC source code: http://aspnet.codeplex.com/releases/view/41742
i'm trying to dynamically add the class attribute to the body tag, and i came across this class. but i can't seem to understand how to use this class. i have something like this in my page class (or panel class, as i tried with that too):
add(new BodyTagAttributeModifier("class", "homepage", this));
this doesn't even compile, saying there's something wrong with the 2nd parameter. but i think String is automatically considered a Model in wicket, like the Label class. am i missing something here?
What if you just add an wicket:id to the body attribute and use the AttributeAppender class? Or, if the body attribute already has an id, can't you just use this class?
http://wicket.sourceforge.net/apidocs/wicket/behavior/AttributeAppender.html
Some Wicket Components have this String-to-model-shortcut (like Label), but it's not a general feature. You have to convert your String into a Model manually:
add(new BodyTagAttributeModifier("class", Model.of("homepage"), this));