LK implements a MVC infrastructure for various uses, such as separation of data presentation and application logic, notification of data mutation, user interface widget construction etc.

LK objects can act either as Views or Models (potentially both).

Every View has its own abstract model, consising of a list of abstract variables that are named by strings, and can be read and/or written using the its getModelValue() and setModelValue() methods. A View connects to a concrete model instance by means of the connectModel() method, which specifies how the model's abstract variables map onto concrete methods of the model's concrete variables.

For instance, a push button's model may contain an abstract boolean variable "Value". The push button may be connected to a concrete model representing a debugger and to control whether call tracing is turned on or off. The push button could be connected to the model by the following statement:

pushButton.connectModel({model: myDebugger, setValue: "setTrace", getValue: "getTrace"});

The push button does not know anything about the particular methods of myDebugger, because the so called model plug, i.e, the object passed as the argument to connectModel(), provides a "translation" from the push button vocabulary ("setValue" and "getValue" strings used by View as in calls to get/setModelValue()) to the debugger's vocabulary, i.e., setTrace() and getTrace() instance methods. Note that in this simplest case any object can act as a Model for other objects and need not implement any special   protocol, because the model plug provides the translation. Views are required to implement several methods, including the aforementioned getModelValue(), setModelValue() and connectModel(), and LK provides a reusable implementation in form of ViewTrait. All Morphs adopt the ViewTrait.
Note also that multiple Views can connect to a single model instance, using different plugs.


In a more complex usage pattern, LK enables Views to be notified when a model variable is updated. To this end, the model instance has to be derived from the Model class provided by LK. The model instance notifies all views of a model change using the changed() method. For instance, myDebugger might invoke this.changed("getTrace") from within its setTrace() method to announce that the tracing behavior is changing. Interested Views can react to this event from within their updateView() method (defined in ViewTrait), invoked automatically by LK. updateView()'s first argument is the name of the model instance variable being modified, in our running example that would be "getTrace". The view can then consult its model plug to see to what variable of its abstract model this name refers to. In this case it is "getValue". The View can then retrieve the new value using getModelVariable("getValue") and update itself to reflect the change in the model.

As it may be obvious from the above, model variables are not required to exist as actual properties of objects, rather, they are represented as pairs of accessor methods, in the above example it would be "getTrace" and "setTrace". Model variable values may be shared internally and/or computed.  However, a very common usage scenario involves creating a model object with an actual Javascript property for every model variable and a stereotyped accessor method pair, with the setter issuing the changed() call to notify views of a model value change, as described above. As a convenience, LK provides a subclass of Model, called SyntheticModel, that generates such accessors dynamically on instantiation. Specifically, SyntheticModel's constructor accepts a list of String arguments representing abstract method names and for every name "Foo" it adds a property "Foo", a getter "getFoo" and a setter "setFoo". SyntheticModels contain entirely stereotyped code, which means that a SyntheticModel is fully recoverable from the list of its property names and values, thus easily persisted.

If a SyntheticModel is developed together with the Views that will operate on it, the model instance may simply use the same variable names as the abstract variable names used by its Views. For this case LK provides a special (optional) convention: a View may have a prototype variable called "pins", which is a list of model variable names that it will access. Every name may be preceded by "+", indicating that the variable be only written, or "-", indicating that the variable will only be read.  For instance, a Morph that acts as a weather widget can specify pins as  ["-Locale", "+Temperature", "+Wind"], indicating that it will read the locale from the model and write Temperature and Wind back to it (because its function may be to fetch the temperature and wind information based on the locale specified). The weather widget may then connect itself to a SyntheticModel using the model's makePlugSpecFromPins() method to create the appropriate model plug. Besides being a convenience, the pins property functions also as documentation, describing the abstract model of a given View, which can otherwise only be elucidated by analysing  get/setModelValue() and connectModel() invocations.
