# HG changeset patch # User Jaroslav Tulach # Date 1449695596 -3600 # Node ID 558934b8b835d228c55c2ad93ad7e2a1226050fe # Parent 4f906bde3a2ef91c075e80d7eced3f477547d7e4 Documenting how to initialize and read private values from the implementation class diff -r 4f906bde3a2e -r 558934b8b835 json/src/main/java/net/java/html/json/Model.java --- a/json/src/main/java/net/java/html/json/Model.java Wed Dec 09 21:39:13 2015 +0100 +++ b/json/src/main/java/net/java/html/json/Model.java Wed Dec 09 22:13:16 2015 +0100 @@ -280,9 +280,71 @@ * data.hello(); * assert data.getMessage().equals("Hello 3 times!"); * + *

* The methods annotated by {@link ComputedProperty} need to remain static, as * they are supposed to be pure functions (e.g. depend only on their parameters) * and shouldn't use any internal state. + *

+ *

How do I initialize private values? + * The implementation class (the one annotated by {@link Model @Model} annotation) + * needs to have accessible default constructor. That constructor is used to + * create the instance. Obviously such constructor does not have + * any parameters, so no initialization is possible. + *

+ *

+ * Later one can, however, call any {@link ModelOperation @ModelOperation} + * method and pass in additional configuration parameters. In the above + * example it should be possible add + *

+ *
+     * {@link ModelOperation @ModelOperation} void init(Data model, int count) {
+     *   this.count = count;
+     * }
+     * 

+ * and then one can initialize the model using the init as: + *

+ *
+     * Data data = new Data();
+     * data.init(2);
+     * data.increment();
+     * data.hello();
+     * assert data.getMessage().equals("Hello 3 times!");
+     * 

+ * Why there has to be default constructor? Because instances of + * classes generated by {@link Model @Model annotation} may be constructed + * by the system as wrappers around existing JavaScript objects - then + * there is nobody to provide additional parameters at construction time. + *

+ *

How do I read private values? + * The methods annotated by {@link ModelOperation} must return void + * (as they can run asynchronously) and as such they aren't suitable for + * returning values back to the caller. In case something like that is + * needed, one can use the approach of the hello method - e.g. + * set value of some {@link Property property} that has a getter: + *

+ *
+     * data.hello();
+     * assert data.getMessage().equals("Hello 3 times!");
+     * 

+ * Or one can use actor-like callbacks. Define callback interface and + * use it in a {@link ModelOperation @ModelOperation} method: + *

+ *
+     * public interface ReadCount {
+     *   public void notifyCount(int count);
+     * }
+     * {@link ModelOperation @ModelOperation} void readCount(Data model, ReadCount callback) {
+     *   callback.readCount(this.count);
+     * }
+     * Data data = new Data();
+     * data.init(2);
+     * data.increment();
+     * data.readCount(count -> System.out.println("count should be 3: " + count));
+     * 

+ * The provided lambda-function callback may be invoked immediately + * or asynchronously as documentation for {@link ModelOperation} + * annotation describes. + *

* * @return true if the model class should keep pointer to * instance of the implementation class