Part III - Applied Learning - The Controller part 3b
Part III - Applied Learning - The Controller
In this chapter, for the purpose of building our simple app on FOAM, you will learn about the following:
- DAOs (Data Access Objects)
- the FOAM DetailView
- the Controller
In the previous chapter, by defining the model (the M of MVC) you described what your data is: a Phone. As mentioned in the Core Concepts of this tutorial, MVC is a classic pattern for breaking up applications into reusable, decoupled components. DAOs further define the model (M) by defining how you store your data. The DetailView (V) is how your data will be presented to the user for viewing and editing. The controller (C) will connect the views with the model.
1. DAO - Data Access Objects
A Data Access Object (DAO) is a generic interface for a collection of objects.
The DAO interface supports fetching and deleting many rows (select, removeAll), fetching and deleting single rows (find, remove) and inserts (put). The interface also includes a rich and extensible query language for filtering, sorting and aggregation.
FOAM’s data storage library contains many implementations of the common DAO interface, such as:
- In-memory (lightning fast, with automatic indexing and query optimization)
LocalStorageandchrome.storage.*IndexedDB- Plain Javascript arrays
- REST services
- XML and JSON files
- MongoDB (in Node.js)
There are also many DAO “decorators” which add extra functionality on top of other DAOs. This spares each DAO’s author from having to reimplement caching, autoincrement, logging and timing.
2. The FOAM DetailView
The FOAM DetailView has a data property which is set to a specified FOAM object.
The FOAM DetailView has a default template which runs through the list of properties on the object and displays their names (or labels, if set) in the left column of a table and their views on the right. Therefore, we don’t really have to define a custom view here.
3. The Controller
At the top level of an app, the controller (C of MVC) is responsible for connecting the views and model. The controller knows nothing about how the app is laid out visually; it just creates the components and binds them together.
Tutorial Application
For this simple app, you will have a small controller with very few parts:
- A
TextFieldfor the search box. - A
ChoiceViewfor the sort order drop-down. - A
DAOListfor the list of phones (from thephones.jsfile).
STEP #1. Enter the following code into a new js file called $PROJECT/Controller.js:
foam.CLASS({
package: 'tutorial',
name: 'Controller',
extends: 'foam.u2.Element',
exports: [
'as data'
],
properties: [
{
name: 'search',
class: 'String',
view: { class: 'foam.u2.TextField', onKey: true }
},
{
name: 'order',
value: Phone.NAME,
view: {
class: 'foam.u2.view.ChoiceView',
choices: [
[Phone.NAME, 'Alphabetical'],
[Phone.AGE, 'Newest']
]
}
},
{ name: 'dao', value: phones },
{
name: 'filteredDAO',
class: 'foam.dao.DAOProperty',
view: {
class: 'foam.u2.DAOList',
rowView: { class: 'tutorial.PhoneCitationView' }
},
expression: function (dao, search, order) {
var expr = foam.mlang.Expressions.create();
return dao.orderBy(order).where(expr.OR(
expr.CONTAINS_IC(Phone.SNIPPET, search),
expr.CONTAINS_IC(Phone.SNIPPET, search)));
}
}
]
});
About the Above Code:
-
Setting
viewto an object like{ class: 'TextField', onKey: true }specifies the class (TextField) that should be used for this view, as well as some arguments to pass to the view, like settingonKeymode totrue. -
searchhas itsviewset toTextField. By default,TextFieldfires updates when it loses focus or the user presses Enter.Setting onKey: truewill make it fire an update on every keystroke. This means that the list of phones for your app will filter as you type. -
orderdefaults to sorting byPhone.NAME.- For each property
somePropon a classMyClass, there is a static property spelledMyClass.SOME_PROPthat is used for sorting and filtering in DAOs. There are several examples of these here.
- For each property
-
orderis displayed as aChoiceViewwhich represents a drop-down box.ChoiceViewexpects an array of choices. Each choice is an array[internalValue, 'user label']. The value of theorderproperty is two-way bound to the current value of the drop-down box.- If you wanted to add a new ordering such as phone storage size, simply add to the
choicesarray like this:[Phone.STORAGE, 'Storage'].
-
daois the master DAO containing all the phones.phones.jscreates a global array calledphones. You set the defaultvalueof yourdaoproperty to this global value.
-
filteredDAOis the interesting DAO. This is the one that actually drives the main view on the page which gets filtered by the search and ordered by the sort order.-
Its view is
DAOList. This view shows a vertical list of rows, one for each entry in the DAO to which it is bound. The view for each row isPhoneCitationViewwhich we’ll define shortly. expressiontakes a function that is treated like a spreadsheet cell: it registers listeners on each of the inputs in the function. Then when any of the inputs changes, the function will be run again and the value offilteredDAOupdated.- In the above code, those inputs are
this.dao,this.orderandthis.search. - The return value becomes the value of
this.filteredDAOwhich will be a sorted and filtered version of the masterthis.dao.
- In the above code, those inputs are
CONTAINS_ICchecks if the string on the left contains the string on the right, ignoring case.
-
The rowView in the DAOList above is called PhoneCitationView. The above code defined this view to specify how to display a summary of a phone for the catalog page. Now, load your app using the default DetailView templates.
STEP #2. Add the following dummy code to the end of Controller.js. After this step the catalog page will not contain any errors:
foam.CLASS({
package: 'tutorial',
name: 'PhoneCitationView',
extends: 'foam.u2.DetailView'
});
STEP #3. Update index.html to be the following:
<html>
<head>
<script language="javascript" src="foam2/src/foam.js"></script>
<script src="Phone.js"></script>
<script src="phones.js"></script>
<script src="Controller.js"></script>
</head>
<body>
<foam class="tutorial.Controller"></foam>
</body>
</html>
If loaded into your browser, you won’t see a working application yet because we need to update the PhoneCitationView which will will do in the next section.
The <foam> tag is convenient for loading a given model and view and inserting it into the DOM.
Conclusion
In this part of the tutorial, we have explained the use of DAOs, the DetailView and the controller in FOAM. You have applied a controller to your app and used DetailView to assess your work. You are now ready to move onto learning about FOAM UI components and add them to your app.
NEXT: Part III - Applied Learning - User Interface Library
Tutorial Menu:
- Getting Started
- Core Concepts
- Applied Learning: Build a Basic App with FOAM