I googled around on how to pass mvc model to knockoutjs and it seems there are two ways:
My approach:
An example:
function MyViewModel(urls) {
var self = this;
self.isLoading = ko.observable(true);
self.items = ko.observableArray();
self.loadData = function() {
$.get(urls.load, function(data) {
// Process data and push into our items array
self.isLoading(false);
});
}
}
var vm = new MyViewModel({
load: '@Url.Action("GetData", "MyItemController")'
});
$(function() {
ko.applyBindings(vm);
viewModel.loadData();
});
This means I have an extra AJAX call for the data, but IMO users are coming to realise that data != UI. The benefit is that my UI can be served out quickly because there is no real data access involved. The data load may take some time depending on the database, volume of data, etc, etc. It also gives my code a very clean separation of concerns.
I use @Html.Raw because there's nothing useful the user can do on the page until the Knockout UI is generated anyway, and any potential trivial time lag due to the extra initial download from writing the JSON into the page is offset by the user not seeing an unnerving delay before the UI is built. I don't have a problem at all with the JSON used to construct my initial view model being directly in my page.
Where I do make efficiency gains is by retrieving any reusable reference data for things like select options (lists of products etc) in a separate dynamic script download from an MVC controller, which then gets cached by the browser. That way they can be reused across view models and the view models only need to store the selected item value.