Adventures in Ruby MVVM – A ViewModel Base Class in Ruby

More Adventures in MVVM Shout it

In my last post, I talked about how to fire events from Ruby code such that .Net code can subscribe and receive them.  I showed a simple implementation of INotifyPropertyChanged; the interface that is essential to MVVM development in WPF and Silverlight.

With that out of the way, I am moving forward to start building a simple ViewModel base class in Ruby that will let me declare notifiable properties with as little ceremony as possible.

Background

Before I get started, I’d like to show what a simple notifiable property in C# looks like.  If you are familiar with MVVM, this code is not new to you:

private string first;
public string First
{
    get { return first; }
    set
    {
        first = value;
        OnPropertyChanged("First");
    }
}

The Same Thing In Ruby

def first
  @first
end
def first=(val)
  @first = val
  on_property_changed :first
end

Generalizing

Already, the Ruby code is more readable (in my opinion).  The cool thing is that we can do better – much, much better. 

By employing meta programming in the base class, these methods can be generated for us.  The result is a ViewModel class that simply declares the properties as notifiable:

class ViewModel < ViewModelBase
  declare_notifiable :first, :last
end

That’s it!  Since the base class provides the property generation code, you can just declare that you want to create properties that are notifiable and you are ready to go.  To make sure that the properties notify when they are set (and ultimately get updated in the View via data binding), make sure to call the methods (as opposed to the @fields):

def update_values
  self.first = "Brian"
  self.last = "Genisio"
end

ViewModelBase code

Here is the base class that makes it all happen.  For the DotNetEvents mixin code, see my previous post.

class ViewModelBase
    include DotNetEvents
    include System::ComponentModel::INotifyPropertyChanged
    declare_event :PropertyChanged

    def self.declare_notifiable( *symbols )
      symbols.each do | symbol |
        define_notifiable_property( symbol )
      end
    end
    def self.define_notifiable_property( property_name )
      class_eval <<-EOS
        def #{property_name}
          @#{property_name}
        end
        def #{property_name}=(val)
          @#{property_name} = val
          on_property_changed :#{property_name} 
        end
      EOS
    end

    def on_property_changed(name)
      PropertyChanged(self, System::ComponentModel::PropertyChangedEventArgs.new(name))
    end
end

Up Next…

Next, I will post about implementing commands in the ViewModel that the View can bind to.  My goal is to get to a completely convention-based approach to commands, much like my C# ViewModel Support.  Stay tuned.

Tags: , , ,

2 Responses to “Adventures in Ruby MVVM – A ViewModel Base Class in Ruby”

  1. Adventures in Ruby MVVM – A ViewModel Base Class in Ruby…

    Thank you for submitting this cool story – Trackback from DotNetShoutout…

Leave a Reply