Generating a viewModel from the UI

401 views
Skip to first unread message

Aaron Powell

unread,
Sep 6, 2011, 12:02:52 AM9/6/11
to knock...@googlegroups.com
I am trying to create a UI which is built up server side (since the data is available as my MVC ViewModel) that I then want to combine with KnockoutJS.

What I'm display is a list of records from our database which can then in turn be edited client side, users can add or remove records from the list, so I thought Knockout seems ideal. The thing is I'm wanting to avoid having the "blank screen while we build a UI in JavaScript" so that there is a progressive enhancement story (no JavaScript means no editing basically).

The problem is that whenever you bind to the UI the observable array of records will override the initial server generated list, getting to the point where there is a 'flicker' as the UI is rebuilt.

So has anyone tried to do this, create a viewModel from an existing UI to make the UI support data binding *and* still work if data binding can't be run (for what ever reason)?

rpn

unread,
Sep 6, 2011, 12:37:03 PM9/6/11
to knock...@googlegroups.com
Hi Aaron-
I have done this type of thing before, but not with observableArrays.  I played with this for a minute, but didn't have time at the moment to get something working.  

Here is how I would approach it though:
  • the goal would be to get the template binding (foreach is a shortcut to the template binding) to behave "normally" with the existing content
  • I would create a wrapper to the template binding
  • In the init, we need to define what our "template" is going to be.  When the real "foreach" binding gets into the "template" binding code, it sees that we don't have a named template and gobbles up the innerHTML of the element and saves it off as our template.  So, we would need to decide what our template is going to be.  You could pass a name in or you could decide to use the first element as a template.  This could obviously cause issues if someone wanted to use multiple elements for each item (each item results in two list items), but would probably be okay.
  • The second thing that we would have to do in init, is make sure that the template binding believes that our current elements are already mapped to array items.  We would want to do something similar to the functionality in ko.utils.setDomNodeChildrenFromArrayMapping where we make sure that the "lastMappingResult" is set, but we don't modify the DOM at all.
Will see if I can get something working for this one.  Hope this gives you an idea.

Aaron Powell

unread,
Sep 12, 2011, 2:15:29 AM9/12/11
to knock...@googlegroups.com
didn't happen to get something working did you ;)

rpn

unread,
Sep 12, 2011, 8:51:14 AM9/12/11
to knock...@googlegroups.com
No, I didn't get a working sample.  I have a start, but never revisited it.  Reverse engineering the lastMappingResult looks a little more difficult than I had hoped.  I will see if I can find some time to take another look.  It definitely seems like an interesting and useful thing to be able to do.

Aaron Powell

unread,
Sep 12, 2011, 8:53:11 AM9/12/11
to knock...@googlegroups.com

Would you be able to post your code thus far, I’d like to have a go at it myself J

 

Aaron Powell
MVP - Internet Explorer (Development) | Umbraco Core Team Member | FunnelWeb Team Member


http://apowell.me | http://twitter.com/slace | Skype: aaron.l.powell | MSN: aaz...@hotmail.com

rpn

unread,
Sep 12, 2011, 9:00:09 AM9/12/11
to knock...@googlegroups.com
Sure, I have to run at the moment, but will post it as soon as I can find it.  The fiddle that I found with the correct name does not have my code in it.  I have to go searching a bit for it.

rpn

unread,
Sep 12, 2011, 12:24:49 PM9/12/11
to knock...@googlegroups.com
Here was my start at it: http://jsfiddle.net/rniemeyer/NgFUR/.   

Mark Hahn

unread,
Sep 12, 2011, 4:29:48 PM9/12/11
to knock...@googlegroups.com
Here was my start

I haven't had time to fully grok your javascript but it appears you are cheating since the one two three data is present in your code.  Isn't it supposed to come from the dom?

Also, wouldn't it be easy to write a jquery function that updates  a model from the dom before the binding happens?  I know it wouldn't be *pure* ko, but the code you have in the jsfiddle also seems unpure in a way.

rpn

unread,
Sep 12, 2011, 4:42:01 PM9/12/11
to knock...@googlegroups.com
I don't think that building the observableArray from the DOM is his objective.  If JavaScript is not available, then he wants the fields to still be available with values.  Additionally, he wants to avoid the flicker of the template binding adding/replacing the content dynamically from templates.

Basically, the template binding needs to accept the existing content, as if it was rendered by the template binding.





Mark Hahn

unread,
Sep 12, 2011, 5:36:12 PM9/12/11
to knock...@googlegroups.com
Surely he isn't going to put the variable data in the html and somewhere else such as the javascript or ajax when he serves the page.  Since he is only putting the data in the html he has to build the observableArray from the dom, even if it isn't his ultimate objective.  The only alternative would be to have the viewmodel not match the dom for some possibly long period of time.  Would that be ok?

I'm currently hiding the entire page until the binding happens to avoid flicker.  I considered using this trick of putting the data in the dom, but I am holding off on doing this because I would have to load the data without the help of KO in the server and then refresh it later using KO.  This is a pretty bad example of repeating myself.

It would be cool if I could use the same KO code on the server side.  Then I would not be repeating any effort.  Is it possible to run KO in node?  Maybe with JSDOM?

rpn

unread,
Sep 12, 2011, 5:46:54 PM9/12/11
to knock...@googlegroups.com
I think that he wants to use observableArrays in their normal fashion to take advantage of the UI updating when items are added/removed.  He simply wants to pre-populate the HTML to avoid the flicker and to provide some level of functionality when JavaScript is off.   My idea allows the template binding to accept the exiting content as if it was generated by the template binding.

The only potentially troubling part is generating/maintaining templates on both server and client-side that generate identical content.

I know that people have used KO with node.  That is not something that I have played with yet.

Mark Hahn

unread,
Sep 12, 2011, 6:15:41 PM9/12/11
to knock...@googlegroups.com
> The only potentially troubling part is generating/maintaining templates on both server and client-side that generate identical content.

It is not only troubling in terms of duplication of coding effort, but sending the data over the wire twice is going to slow things down.  So there are really two problems.

I feel the ultimate solution requires that KO generate the initial HTML in the server, and send it with an empty view model to the client.  Then the client would run something to copy the data in html (the dom) to the empty view model.  Any other solution is a compromise.

Aaron Powell

unread,
Sep 12, 2011, 7:28:20 PM9/12/11
to knock...@googlegroups.com

I don’t think that Knockout needs to be responsible server-side to generate the HTML, in fact I don’t see it really being that advantageous. My server layer happens to be ASP.Net MVC so I don’t exactly have a server runtime but I can easily create a way to generate the HTML both populated and for templating without having a duplicate code effort.

 

What Ryan said is correct, I want to use an observableArray as normal so when items are added/ removed from it the UI will be updated to reflect the change, and I want the initial data to be built from the DOM, rather than from JavaScript as it would result in KO doing a rebuild of the DOM after its rendered which to me doesn’t make sense (and the flick between the two modes is a poor user experience).

 

Aaron Powell
MVP - Internet Explorer (Development) | Umbraco Core Team Member | FunnelWeb Team Member


http://apowell.me | http://twitter.com/slace | Skype: aaron.l.powell | MSN: aaz...@hotmail.com

 

From: knock...@googlegroups.com [mailto:knock...@googlegroups.com] On Behalf Of Mark Hahn
Sent: Tuesday, 13 September 2011 8:16 AM
To: knock...@googlegroups.com
Subject: Re: Generating a viewModel from the UI

 

> The only potentially troubling part is generating/maintaining templates on both server and client-side that generate identical content.

rpn

unread,
Sep 12, 2011, 8:19:57 PM9/12/11
to knock...@googlegroups.com
I stand by my sample as a good way to accomplish the original goal.  It allows you to associate existing array items with existing DOM elements in a generic way.

In my experience, recreating the view model from only the DOM is not an ideal experience.  For example, in my sample, the objects have an id and a name.  The id does not appear in the markup at all.  If you were going to just use the DOM, then you would have to account for all of the data that makes up your object, scrape it from the DOM, and construct the object.  In some cases, your object may have nested objects inside of it or a complex structure that is not exposed in the initial view.

I think that sending both the initial HTML and the data over-the-wire is probably not a big concern to someone that values this functionality.  I do agree that maintaining some kind of templates on the client and server is not ideal.

However, If there are other ideas for this type of thing, then I would be happy to help explore them as well. 


Aaron Powell

unread,
Sep 12, 2011, 8:23:19 PM9/12/11
to knock...@googlegroups.com

I’ve had a play with your sample and it looks good. I do see your point about creating the whole object from the DOM (and the potential to miss data). I’m going to do some experimenting (hopefully) today with it and seeing if we can use this concept in our app J.

 

Aaron Powell
MVP - Internet Explorer (Development) | Umbraco Core Team Member | FunnelWeb Team Member


http://apowell.me | http://twitter.com/slace | Skype: aaron.l.powell | MSN: aaz...@hotmail.com

 

From: knock...@googlegroups.com [mailto:knock...@googlegroups.com] On Behalf Of rpn
Sent: Tuesday, 13 September 2011 10:20 AM
To: knock...@googlegroups.com
Subject: Re: Generating a viewModel from the UI

 

I stand by my sample as a good way to accomplish the original goal.  It allows you to associate existing array items with existing DOM elements in a generic way.

Mark Hahn

unread,
Sep 13, 2011, 12:26:08 AM9/13/11
to knock...@googlegroups.com
I don't mean to be dragging this thread out, but I'm interested as I, and probably many others, are facing a similar problem.

 but I can easily create a way to generate the HTML both populated and for templating without having a duplicate code effort.

Can you give a short description of how you do this?  In my app the html generation and the viewmodel generation are as different as night and day.

codedat...@gmail.com

unread,
Aug 25, 2013, 3:51:23 AM8/25/13
to knock...@googlegroups.com, ma...@boutiquing.com
I am trying to use a PE principles with the knockout js. In the first phase, I created special bindings for knockout that use the generated HTML from server side. I like to extend the work and please if you have any idea or suggestion, let me know. here is the address of the first post on the topic.
Reply all
Reply to author
Forward
0 new messages