Binding to dynamically Generated HTML with new Bindings

4 posts, 0 answers
  1. Ralph Quintero
    Ralph Quintero avatar
    5 posts
    Member since:
    Jan 2008

    Posted 23 Jul 2014 Link to this post

    I am currently working on a Web page which is built dynamically, not only on the initial page load, but also updating the page via REST-based service calls which return HTML fragments (containing their own "data-bind" tags) as well as portions of JavaScript meant to augment the observable object.

    I have a simple ViewModel which looks like the following:

    var viewModel = kendo.observable({ name: "Test", html: "" });


    Inside the Web page, I have both an <input> element and a <div> element (acting as a placeholder) which looks like something below:

    <div id="mainView">
       <input type="text" data-bind="value: name" />
       <div data-bind="html: html"></div>
    </div>


    In the JavaScript, the view is correctly bound in my $(document).read() :

    kendo.bind($("#mainView"), viewModel);


    Now, I make a REST-based service call which return the following fragment (as variable 'htmlFragment'):

    <input type="text" data-bind="value: name" />

    I then set the 'html' member of my ViewModel:  

    viewModel.set("html", htmlFragment);

    I am seeing the following occur: a) The text box appears with the value "Test"; and b) after the service call, a new text box appears, but without any data.  Now, changing the text box originally rendered will update the ViewModel, but the second text box will not.  The HTML (with the same binding as the first generated text box) is injected into the DOM with the correct data-bind tag, but no binding occurs on the element.

    For lack of any other methods I decided to again call kendo.bind($("#mainView"), viewModel) after the service call and after the HTML injection and it then apparently binds correctly and now both text boxes are synchronized.  All of that being said, here are my questions:

    a) Is there inherently anything wrong with calling the kendo.bind() method multiple times if either the ViewModel and/or DOM are augmented with new members/bindings?
    b) Is there any way to 'refresh' the bindings without calling bind() again (as I don't know how other UI elements will behave yet)?
    c) Is it possible to hook the change event (not specifically for a particular named binding, but for a binding type (i.e. "html" binding) and just refresh the bindings for that particular HTML fragment?

    Any information or suggestions would be greatly appreciated, thank you!
  2. Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 25 Jul 2014 Link to this post

    Hi Ralph,

    The approach you are using is a viable one. There is nothing wrong with multiple kendo.bind calls apart from performance implications if you call it multiple times on large chunks of html. Using the change event for that case may be problematic (and may result in a in a endless recursion error). In general, the change event is meant to react to changes of the view model - it does not pass information about its bindings. 

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. Kendo UI is VS 2017 Ready
  4. Ralph Quintero
    Ralph Quintero avatar
    5 posts
    Member since:
    Jan 2008

    Posted 25 Jul 2014 in reply to Petyo Link to this post

    Greets,

    Thank you for the confirmation.  It seemed like the best approach and I would definitely like to eliminate the possibility of recursion (so the 'changed' event is out, more so because we can't get binding information).

    After some experimentation, I found that I could bind the same ViewModel directly to the element that I add using jQuery (instead of HTML binding), for example:

    kendo.bind($("#htmlFragmentDiv").html(htmlFragment), viewModel);

    That being said are there any issues or overhead considering it is only binding to the small fragment of HTML (which is a child element of the outer bound view)?

    One other thing that I would like to note (which is why I chose to use jQuery above), and I don't know if this is by design or an oversight.  I am having a problem using an 'html' binding to a <script> element which retrieves an external JavaScript:

    <script type="text/javascript" src="../Scripts/testscript.js"></script>


    When I set the appropriate binding on the ViewModel, the <script> element is added to the DOM, however, no request is made to retrieve the script.  On the other hand, if I use the jQuery $.html() to add the HTML to the same <div> on which I have the HTML binding, it adds the script element (exactly the same as the HTML binding), but also makes a request to retrieve the JavaScript file.

    It would really be nice if we can use an HTML binding to get the same behavior as setting the innerHTML using jQuery.  I suppose I could create a custom binding, but it would be more useful baked into the existing HTML binding that Kendo offers. 

    Thank you!
  5. Petyo
    Admin
    Petyo avatar
    2438 posts

    Posted 28 Jul 2014 Link to this post

    Hi Ralph,

    jQuery does a lot of magic in order to evaluate external script tags injected through the html() call. Using that by default would be a significant performance hit. You may, however create a custom binding which uses the jQuery html method.

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready