The-M-Project icon indicating copy to clipboard operation
The-M-Project copied to clipboard

Pre- and Post-rendering callbacks for view

Open sebastianwerler opened this issue 12 years ago • 6 comments

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.

sebastianwerler avatar Jun 28 '12 11:06 sebastianwerler

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

hano avatar Jul 02 '12 16:07 hano

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:

  1. 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.
  2. 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.

sebastianwerler avatar Jul 02 '12 16:07 sebastianwerler

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..

kailash657 avatar Jul 04 '12 13:07 kailash657

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

sebastianwerler avatar Jul 04 '12 18:07 sebastianwerler

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)...

sebastianwerler avatar Jul 04 '12 21:07 sebastianwerler

Yes that would be nice indeed.. can't wait for 1.3 then!

kailash657 avatar Jul 09 '12 09:07 kailash657