The-M-Project
The-M-Project copied to clipboard
Pre- and Post-rendering callbacks for view
It exists the requirement to style a view depending on the value it receives.
Example: once a label has the value 'Completed' it shall be displayed in green text color. If its value is 'Aborted' it shall display the value in red text color.
Dynamic Value Computing is for amending the value that is passed on the view. Changing the style of the view doesn't work here, because the value is already rendered to html but not yet appended to the DOM. And even if it would work here, it would be wrong to do style computing here, 'cause this concept is here for amending the value, not the style of the view.
Therefor, pre and post render callbacks shall be implemented.
I'd had a similar issue and builded a workaround like this one: label:M.LabelView.design({ computedValue: { contentBinding: { target: appName.Controller, property: 'count' }, value: '', operation: function(v) { var color = 'green'; if(v === "1"){ color = "red"; }else if(v === "2"){ color = "blue" } return '' + v + ''; } } }) mobileCRM.LoginController.set('count', '1');
I thought also about an Object that is set to an label with a value to be displayed and a value as identifier. Similar to the M.ListItemView { display: "You have a new message", value: 3 }
and then use it somehow like this:
operation: function(v) { var color = 'green'; if(v.value === "1"){ color = "red"; }else if(v.value === "2"){ color = "blue" } return '' + v.display + ''; }
What's you opinion on this?
regards marco
This fits to the problem that you want to have different colors. There's several other workarounds that fix this, too. I've got my doubts with these solutions, 'cause they're kind of dirty:
- The value is filled with view information (e.g. the "span" tag you've added). The label itself already has all necessary things to show the value. I'd like to use what comes out of the box because this is enough.
- Your solution fixes the problem of different colors, but what if you'd like to hide a view based on a value and show it, once the value has changed to a different one.
With pre and post render functions I can operate on the view without having to introduce new tags or use the value as a way to smuggle in other HTML tags.
Hi all, and thank you hano for inviting me to this thread..
I think that pre and post processing function would be a very useful thing to have but I have been thinking all yesterday about something different.
I really like computing values for views, and it would be super cool if it was possible to compute other properties in the view object in a similar way
Disclaimer: what I'm going to write next is just pure brainstorming stuff maybe it doesn't have any sense because I don't know how the m project internals work and I am more a php programmer than a javascript one.
Suppose we have a little object wrapping a function like this
M.ComputedProperty = M.Object.extend({ operation : function(){} });
Then we have a listview and its data objects could look like this { name : 'Name', is_different : YES/NO }
Then the template for the list items could be like that
ListItemTemplate = M.ListItemView.design({
childViews: 'name',
computedProperties : 'cssClass',
name: M.LabelView.design({
valuePattern: '<%= name %>'
}),
/*
the operation function should be executed when observed content changes, before rendering
and the object corresponding to the view should be passed as parameter
*/
cssClass : M.ComputedProperty.extend({
operation : function(obj){
if(obj.is_different)
return "different-css-class";
else
return "";
}
}),
/*maybe wilder things could be done like this: */
events : M.ComputedProperty.extend({
operation : function(obj){
if(obj.is_different)
return {
tap: {
target:MyApp.DifferentController,
action:'itemSelected'
}
}
else
return {
tap: {
target:MyApp.AnotherContreller,
action:'anotherMethod'
}
}
}
}),
});
I tried hacking at M.View code but I didn't have enough time to really understand how content binding and rendering works..
Hi Giovanni,
thanks for your ideas. Your suggestions do really make sense and we've had sth. like your ideas already in mind.
The pre and post renderers will get the view object passed as parameter. That means you can operate on all its values, also the event stuff (although it doesn't make sense in post renderer because events are already binded then... hmmm... could be an option to rebind them then.).
We'll not merge this with computedValue but make two other methods because computedValue is for computing the value to be shown, e.g. transforming a timestamp into a data or add a prefix to the value, translate it or something else. All view or styling related stuff shouldn't go in there, although it would work. But it makes no sense semantically and on a conceptual level.
We plan to integrate this kind of methods for v1.3 which is planned for end of august. We're always appreciating new ideas, so please keep asking and making suggestions! Or best: be part of the guys that implement it :)
You can read about content binding in TMP here: http://panacodalabs.github.com/The-M-Docs/#core_concepts/content_binding
The render process is somehow more complex. There's no other way but to read the code of the M.View, all other views and event framework code to understand it in total.
Best regards Sebastian
Another part where pre rendering based on a value is totally necessary is the ListView. It would be nice to be able to only show the list, if there's values available and otherwise show a default view (which could be part of the ListView, e.g. as NoDataChildView)...
Yes that would be nice indeed.. can't wait for 1.3 then!