@Retention(value=SOURCE) @Target(value=TYPE) public @interface Model
className(). The generated class contains
getters and setters for properties defined via properties() and
getters for other, derived properties defined by annotating methods
of this class by ComputedProperty. Each property
can be of primitive type, an enum type or (in order to create
nested JSON structure)
of another class generated by @Model annotation. Each property
can either represent a single value or be an array of its values.
The generated class's toString method
converts the state of the object into
JSON format. One can
use Models.parse(net.java.html.BrwsrCtx, java.lang.Class, java.io.InputStream)
method to read the JSON text stored in a file or other stream back into the Java model.
One can also use @OnReceive annotation to read the model
asynchronously from a URL.
An example where one defines class Person with four
properties (firstName, lastName, array of addresses and
fullName) follows:
The generated model class has a default constructor, and also quick instantiation constructor that accepts all non-array properties (in the order used in the@Model(className="Person", properties={@Property(name = "firstName", type=String.class),@Property(name = "lastName", type=String.class)@Property(name = "addresses", type=Address.class, array = true) }) static class PersonModel {@ComputedPropertystatic String fullName(String firstName, String lastName) { return firstName + " " + lastName; }@ComputedPropertystatic String mainAddress(List<Address>addresses) { for (Address a : addresses) { return a.getStreet() + " " + a.getTown(); } return "No address"; }@Model(className="Address", properties={@Property(name = "street", type=String.class),@Property(name = "town", type=String.class) }) static class AddressModel { } }
properties() attribute) and vararg list
for the first array property (if any). One can thus use following code
to create an instance of the Person and Address classes:
Person p = new Person("Jaroslav", "Tulach",
new Address("Markoušovice", "Úpice"),
new Address("V Parku", "Praha")
);
// p.toString() then returns equivalent of following JSON object
{
"firstName" : "Jaroslav",
"lastName" : "Tulach",
"addresses" : [
{ "street" : "Markoušovice", "town" : "Úpice" },
{ "street" : "V Parku", "town" : "Praha" },
]
}
In case you are using Knockout technology
for Java then you can associate such model object with surrounding HTML page by
calling: p.applyBindings(); (in case you specify targetId().
The page can then use regular
Knockout bindings to reference your
model and create dynamic connection between your model in Java and
live DOM structure in the browser:
Name: <span data-bind="text: fullName"> <div data-bind="foreach: addresses"> Lives in <span data-bind="text: town"/> </div>
model class (with appropriate
Knockout observable properties)
by calling Models.toRaw(p). For
example here is a way to obtain the value of fullName property
(inefficient as it switches between Java and JavaScript back and forth,
but functional and instructive) via a JavaScript call:
The above shows how to read a value from Knockout observable. There is a way to change the value too: One can pass a parameter to the property-function and then it acts like a setter (of course not in the case of read only@JavaScriptBody(args = "raw", javacall = true, body = "return raw.fullName();" // yes, the Knockout property is a function ) static native String jsFullName(Object raw); // and later Person p = ...; String fullName = jsFullName(Models.toRaw(p));
fullName property,
but for firstName or lastName the setter is
available). Everything mentioned in this paragraph applies only when
Knockout technology is active
other technologies may behave differently.
model class instance
by copy and convert
the the whole object into plain
JSON. Just
print it as a string and parse it in JavaScript:
@JavaScriptBody(args = { "txt" }, body =
"return JSON.parse(txt);"
)
private static native Object parseJSON(String txt);
public static Object toPlainJSON(Object model) {
return parseJSON(model.toString());
}
The newly returned instance is a one time copy of the original model and is no longer
connected to it. The copy based behavior is independent on any
particular technology and should work
in Knockout as well as other
technology implementations.
Model annotation or try
a little math test.| Modifier and Type | Required Element and Description |
|---|---|
String |
className
Name of the model class.
|
Property[] |
properties
List of properties in the model.
|
public abstract String className
public abstract Property[] properties
public abstract String targetId
applyBindings method
in the model class is going to be generated which later calls
Models.applyBindings(java.lang.Object, java.lang.String)
with appropriate targetId. If the targetId
is specified as empty string, null value is passed
to Models.applyBindings(java.lang.Object, java.lang.String) method.
If the targetId is not specified at all, no public
applyBindings method is generated at all (a change compared
to previous versions of this API).applyBindings() method toCopyright © 2015 NetBeans. All Rights Reserved.