I had to create a 'wizard' type feature using knockout sometime ago. You could do something like this:
var steps = ko.observableArray([
{ stepName: "step1", person: viewModel1 },
{ stepName: "step1", person: viewModel2 }
]);
Firstly, it is worth noting that your steps array need not be an observable if you're not going to be modifying it once it has been populated. Second, you also might not need to have a step number - I assume that is what the 1 represents in the line:
new WizardStep(1, "step1")
Because arrays are ordered you're storing information you already have which is contained in the index of each element in your steps array. i.e. steps[0] would be step1 and so forth. If you need to keep track of where you are in your wizard you can create an observable in your viewModel and a function to set the step you're currently on like so:
var self = this;
self.currentStep = ko.observable(0); // starting step
self.goToStep = function(index){
self.currentStep(index);
};
Or you could:
var self = this;
self.currentStep = ko.observable(steps()[0]); // starting step
self.goToStep = function(index){
self.currentStep(steps()[index]);
// if you only need the viewModel associated with this step you could use:
self.currentPerson(steps()[index].viewModel.name);
};
In your view you can then use a knockout if binding to conditionally show or hide the step you are currently on / simply render the viewModel held in self.currentStep() and data-bind to a click event, for example.
If you really want to be able to access the step by stepName then you can use knockouts arrayFirst utility function:
self.getStepByName = function(stepName){
return ko.utils.arrayFirst(steps(), function(step) {
return step.stepName() === stepName;
});
};
I'll let you to fill in the blanks and the missing declarations. You could also do something using computeds or writable computeds. At the end of the day there are many ways to skin a cat. I'm sure any one of the solutions offered here are viable.