Created
August 5, 2012 11:28
-
-
Save yreynhout/3264054 to your computer and use it in GitHub Desktop.
Viewmodels - Sample 5
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
var ThingDetailViewModel = function() { | |
if (!this instanceof ThingDetailViewModel) { | |
return new ThingDetailViewModel(); | |
} | |
var self = this, | |
states = { none: 0, adding: 1, modifying: 2}, | |
statemachine = new SimpleStatemachine(states.none), | |
baseData = null, | |
buildCommand; | |
self.Name=new TextInput(); | |
//more inputs go here ... | |
self.Save=new Trigger(); | |
self.Cancel=new Trigger(); | |
// Example of viewmodel self-contained behavior, | |
// i.e. not every behavior needs to relay to the controller. | |
self.Cancel.setCallback(function() { | |
if(statemachine.isState(states.adding)) { | |
//clear and disable inputs | |
self.Name.clear(); | |
self.Name.disable(); | |
self.Save.disable(); | |
self.Cancel.disable(); | |
} else if(statemachine.isState(states.modifying)) { | |
//reset inputs | |
self.Name.setValue(baseData.Name); | |
} | |
}); | |
// Explicit installment of the controller into the viewmodel | |
self.installController = function(controller) { | |
ns.guard.notnull({ controller: controller }); | |
ns.guard.hasmethods(controller, ['saveThing']); | |
// bind any callbacks to the controller | |
self.Save.setCallback(function() { | |
controller.saveThing(baseData.Id); | |
}); | |
}; | |
// Called by the controller with an empty data skeleton | |
self.addThing = function(data) { | |
ns.guard.notnull({data:data}); | |
statemachine.transitionTo(states.adding); | |
baseData = data; | |
self.Name.setValue(data.Name); | |
self.Name.enable(); | |
self.Save.enable(); | |
self.Cancel.enable(); | |
self.Name.focus(); | |
}; | |
// Called by the controller with data gotten from the server | |
self.modifyThing = function(data) { | |
ns.guard.notnull({data:data}); | |
statemachine.transitionTo(states.modifying); | |
baseData = data; | |
self.Name.setValue(data.Name); | |
self.Name.enable(); | |
self.Save.enable(); | |
self.Cancel.enable(); | |
self.Name.unfocus(); | |
}; | |
// Called by the controller to know if something was changed, | |
// which gets delegated to its composed parts | |
self.hasChanges=function() { | |
if(statemachine.isState(states.none)) return false; | |
if(statemachine.isState(states.adding)) return true; | |
return self.Name.isChanged(); | |
}; | |
// Called by the controller to fetch the changes that should be | |
// sent to the server (command, request, data, whatever floats your boat) | |
self.getChanges=function() { | |
if(!self.hasChanges()) { | |
return []; | |
} | |
return [buildCommand()]; | |
}; | |
// Called by the controller to indicate changes are not longer pending | |
self.acceptChanges=function() { | |
self.Name.acceptChange(); | |
}; | |
buildCommand=function() { | |
//Oh no's we're in CQRS land here ... | |
}; | |
// Called by the controller to see if the model is valid, | |
// where this is the simplest of examples. | |
self.validate = function() { | |
return self.Name.validate(); | |
}; | |
//more behavior goes here ... | |
}; | |
var ThingController = function(queryApi, commandBus, dialogService) { | |
if (!this instanceof ThingController) { | |
return new ThingController(queryApi, commandBus, dialogService); | |
} | |
var self = this, | |
viewModel = null, | |
listItemFactory = new ThingListItemViewModelFactory(self), | |
...; | |
// Example of binding the view model to the controller, | |
// which could be done in many ways. | |
self.init=function(thingViewModel) { | |
viewModel=thingViewModel; | |
viewModel.installController(self); | |
}; | |
// Example of flow and coordination activity | |
self.saveThing = function(idOfThingToSave) { | |
if(viewModel.hasChanges()) { | |
if(viewModel.validate()) { | |
commandBus.sendBatch(viewModel.getChanges(), { | |
success: function() { | |
viewModel.acceptChanges(); | |
}, | |
failure: function(error) { | |
dialogService.showError(error); | |
} | |
}); | |
} | |
} | |
}; | |
// many more methods go here ... | |
}; |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment