-
Notifications
You must be signed in to change notification settings - Fork 152
Dynamic Value Computing (The M Project 1.x)
Dynamic Value Computing is a special feature within our framework to enrich the default Data Binding with the functionality to dynamically generate an output value based on both a bound property and a custom method, that is applied to this value right before it is output. So for example you are able to format an M.LabelView
or to add CSS classes based on the given value. Besides processing single values, it is also possible to use Dynamic Value Computing with our M.ListView
to apply a custom method to multiple uniform elements in a row.
To explain you how to use Dynamic Value Computing, it is the best to dive right into some sample code:
label: M.LabelView.design({
computedValue: {
contentBinding: 'SampleApp.MyController.aNumber',
value: 0,
operation: function(v) {
return M.Math.pow(v, 2);
}
}
})
As you can see, we defined an M.LabelView
and its computedValue
property. This property is kind of the trigger for using Dynamic Value Computing at all. Now everytime the bound controller property, SampleApp.MyController.aNumber
, changes, the method defined with the operation
property is applied to the value and the result of this method is then assigned to the label's value. For example, let's say SampleApp.MyController.aNumber
is set to 4, then this number is passed as he first parameter, v
, to our custom method. So internally this method looks like:
return M.Math.pow(4, 2);
The result of this operation, 16, is then assigned to the label's value.
What you should know so far is what Dynamic Value Computing basically means and that there is a view property called computedValue
available. Now we will take a look at a real example app. Let's say our app has a simple button and everytime we click this button, a controller property counting these clicks is increased. Besides this button, there are two labels defined, the first simply displays the number of clicks, the second displays this number squared. What we could do to solve this problem is to create two controller properties that are individually set every the button is clicked. But to keep the controller as simple as possible and to encapsulate view-related things within the view itself, we will use Dynamic Value Computing instead. Now let's take a look at our view:
DynamicValueComputing.app = M.Application.design({
page: M.PageView.design({
childViews: 'content',
content: M.ScrollView.design({
childViews: 'label1 label2 button1',
label1: M.LabelView.design({
contentBinding: 'DynamicValueComputing.CountController.numberOfClicks',
value: '0'
}),
label2: M.LabelView.design({
computedValue: {
contentBinding: 'DynamicValueComputing.CountController.numberOfClicks',
value: 0,
operation: function(v) {
return M.Math.pow(v, 2);
}
}
}),
button1: M.ButtonView.design({
value: 'Click Me',
target: BindingSample.CountController,
action: 'addClick'
})
})
})
});
As you can see, label1
simply uses the contentBinding
property to display the nuber of clicks stored in the CountController
's numberOfClicks
property. The second label instead, label2
, uses the computedValue
property to apply a method to this bound value. So after e.g. 10 clicks, the first label will display a simple 10
. The second label instead will compute the square of this value and display a 100
. But neither the button nor the controller now about this computation. Only the view, label2
, that is responsible for displaying it, nows this computed value. So the whole process is totally encapsulated within the view itself.
As mentioned above, you can also use Dynamic Value Computing with M.ListView
. It basically works the same as with a normal view, only that we do not use the contentBinding
property but the valuePattern
property within our templateView. The following code snippet shows how this could look:
// Here we define our list view
myList: M.ListView.design({
contentBinding: 'ListApp.ListController.listItems',
listItemTemplateView: ListApp.ListItemView
})
// ...
// Here we define our list view's list item template view
ListApp.ListItemView= M.ListItemView.design({
childViews: 'label1',
label1: M.LabelView.design({
computedValue: {
valuePattern: '<%= property1 %>',
operation: function(v) {
return '_' + property1 + '_';
}
}
})
});