I am mostly wondering how to organize things like modal windows, and dynamic pages like profiles. Should the viewModel only contain one profile view or contain all profiles loaded? This here just doesnt seem very "clean".
viewModel = { profile: ko.observableArray([ new ProfileViewModel() //... any others loaded ]) , createPostModal: { input: ko.observable() , submit: //do something to submit... } } <div data-bind="foreach: profile"><!-- profile html --></div> <div data-bind="with: createPostModal"></div>
This way doesn't seem very consistent. Is there anybody who has built a single page app with knockout that can offer some advice? Code samples would be appreciated.
We are just starting down this path at work, and so are not quite sure what we're doing. But here's the idea we have.
The page should be composed of any number of "components," possibly nested. Each component has a view model and one public method, renderTo(el)
, which essentially does
ko.applyBindings(viewModelForThisComponent, el)
It also could have the ability to render subcomponents.
Constructing or updating a component consists of giving it a model (e.g. JSON data from the server), from which it will derive the appropriate view model.
The app is then created by nesting a bunch of components, starting with a top-level application component.
Here is an example for a "hypothetical" book-managing application. The components are LibraryUI
(displays a list of all book titles) and DetailsUI
(a section of the app that displays details on a book).
function libraryBookViewModel(book) { return { title: ko.observable(book.title), showDetails: function () { var detailsUI = new BookDetailsUI(book); detailsUI.renderTo(document.getElementById("book-details")); } }; } function detailsBookViewModel(book) { return { title: ko.observable(book.title), author: ko.observable(book.author), publisher: ko.observable(book.publisher) }; } function LibraryUI(books) { var bookViewModels = books.map(libraryBookViewModel); var viewModel = { books: ko.observableArray(bookViewModels); }; this.renderTo = function (el) { ko.applyBindings(viewModel, el); }; } function BookDetailsUI(book) { var viewModel = detailsBookViewModel(book); this.renderTo = function (el) { ko.applyBindings(viewModel, el); }; }
Note how we could make the book details appear in a jQuery UI dialog, instead of in a singleton #book-details
element, by changing the showDetails
function to do
var dialogEl = document.createElement("div"); detailsUI.renderTo(dialogEl); $(dialogEl).dialog();
There are 3 frameworks out there that help with creating SPAs using Knockoutjs.
I have used Durandal and I really like it. Easy to use and has a lot of nice configurations so you can plug-in your own implementations. Also, Durandal is created by the same creator of Caliburn which was an very popular framework for building Silverlight/WPF applications.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With