Model Controls

Model controls in APS JS SDK allow binding UI widgets with the data stored locally in the browser (client) and remotely in the APS database (server).

In this document:

Overview

Developers can use two types of data stores bound with widgets:

  • Local data store having bidirectional (two-way) binding with widgets

  • Local data store communicating with the backend data source (APS controller) and providing data to widgets

Therefore, there are two main data models:

  • Model is a local data store that serves exclusively for bidirectional binding with widgets.

    • It works on the client side only.

    • It initializes the bound widgets with new data it initially gets from another source, for example, from a Store object.

    • It listens to changes in bound widgets and updates itself respectively.

  • Store is a local data store that may serve both for communicating with the remote data source (APS controller) and for one-way binding with widgets that need data to display on a screen.

    • It is a way to operate with backend by means of GET, PUT, POST, and DELETE operations.

    • Some widgets, like Grid and Select, can read data from a Store.

Examples

Declare Store

In the following code, a declared Store object will manage APS resources of the specified APS type (offer):

require([
   "aps/ResourceStore",
   ...,
   "aps/ready!"
], function (Store, ...) {
      var offerStore = new Store({
         apsType:    "http://aps-standard.org/samples/vpscloud/offer/1.0",
         target:     "/aps/2/resources/" + aps.context.vars.cloud.aps.id + "/offers"
...
});

It is possible to add a Resource Query Language filter to the store declaration using the baseQuery property. For example, to extract the links with other resources, you can assign the select filter to the baseQuery property. In the following code, the linked offer will be available for each requested VPS:

var vpsStore = new Store({
   apsType: "http://aps-standard.org/samples/basic/vps/2.0",
   target: "/aps/2/resources/",
   baseQuery: "select(offer)"
});

If the store declared above is used in a grid, the following column will represent offers linked to VPSes through the offer link:

{ field: "offer.name",     name: "Offer" }

Bind Store to Widget

To output resources from the Store declared in the previous example, bind the store to a Grid that will output the received APS resources (offers):

load(["aps/PageContainer", { id: "page" }, [
   ["aps/Grid", {
      id:                "grid",
      columns:   [
         { field: "offername",             name: "Name", type: "resourceName" },
         { field: "hardware.memory",       name: "RAM, MB" },
         ...
      ],
      store: offerStore
   }, ...
   ]
]]);

Initialize Model from JSON Representation

In this example, a Model object is initialized from a file containing JSON representation of a new offer with default properties.

require([
   "aps/ResourceStore",
   ...
   "dojo/text!./newoffer.json",
   "aps/ready!"
], function (Store, ..., newOffer) {
   /* Declare the data source */
      var model = JSON.parse(newOffer);
      ...
});

Bind Model to Widgets

When creating a new offer, use the Model object from the previous example to sync with the input widgets. Use the at() method for this.

var widgets =
   ["aps/PageContainer", { id: "page"}, [
      ["aps/FieldSet", { title: true}, [
         ["aps/TextBox", {
            id: "offerName",
            label: _("Offer Name"),
            value: at(model, "name"),
            required: true
         }],
         ["aps/TextBox", {
            label: _("Description"),
            value: at(model, "description")
         }]
      ]],
      ...
   ]];
load(widgets);

Update Remote Data Store

Once a user has completed modification of a resource, the synced Model object must be saved in the remote data source. The normal way is to use the Store object to send the resource representation from the Model object to the APS controller:

when(vpsStore.put(getPlainValue(model)),
   function() { ... }
);