0

I have a situation where I have to update a view model property based on some cases. viewmodel property to update is IsPrintable base on IsPrintableFlag() result. Currently I am updating the property from controller like model.IsPrintable = model.IsPrintableFlag(items, pages);

My question is Instead of updating Viewmodel property from Controller, do we have option to set value of property in viewmodel?

ViewModel Code:

public bool IsPrintable { get; set; }

public bool IsPrintableFlag(IList<Items> items,IList<Pages> pages )
        {
            switch (id)
            {
                case 1:
                case 2:
                    if (!pages.Any())
                    {
                        return pages.Any();
                    }
                    break;

                case 3:
                    return false;
                default:
                    return false;
            }

            return false;
        }

Controller code:

model.IsPrintable = model.IsPrintableFlag(items, pages);
Kurkula
  • 6,386
  • 27
  • 127
  • 202
  • 1
    You may be interested in [this answer](http://stackoverflow.com/a/3511984/3581917), which explains a little more about how James's service layer can be viewed in the context of the MV(C)VM architecture. – Evil Dog Pie Jul 09 '14 at 09:26

2 Answers2

1

A view model shouldn't really contain logic, it should only contain data required by the view. Populating the view model in the controller is fine.

I would recommend you introduce a service layer which wraps up this type of logic e.g.

public class MyDomainService
{
    public bool IsPrintable(IList<Items> items, IList<Pages> pages)
    {
        return ...;
    }
}
...
model.IsPrintable = domainSvc.IsPrintable(items, pages);

Alternatively you could extend this to return a fully populated view model

public MyViewModel GetViewModel(...)
{
    var model = ...;
    model.IsPrintable = this.IsPrintable(items, pages);
    return model;
}
James
  • 80,725
  • 18
  • 167
  • 237
0

Got Answer to my question and want to share so that it might be useful for many people who might face similar issue.

You could actually even set the values within your IsPrintableFlag() method so that you wouldn't need to return a boolean value as well using :

// Define this method within your ViewModel class
public void SetPrintableFlag(IList<Items> items, IList<Pages> pages)
{
      // Assuming id is a property of your ViewModel class
      switch (id)
      {
                case 1:
                case 2:
                    // If there aren't any pages
                    if (!pages.Any())
                    {
                        // Then set your flag to the opposite (you could likely return true here instead)
                        IsPrintableFlag = pages.Any();
                    }
                    break;
                case 3:
                default:
                    IsPrintableFlag = false;
      }
}

Controller Code

model.SetPrintableFlag(items,pages);
Kurkula
  • 6,386
  • 27
  • 127
  • 202
  • 1
    This solution not only breaks the general rules of how a view model should be used, but it's overly complicated (you don't even need a switch statement). – James Jul 10 '14 at 17:14