Search code examples
jquery-templatesjsrenderjsviews

view() returns empty view


i have included jsview.js from http://www.jsviews.com/download/jsviews.js (includes JsRender, JsObservable and JsViews). also i have html table with rendered rows.

and i need execute 3 cases:

  1. delete old rows and insert new rendered rows to the table, having done some operations with them (initialization and etc.) before inserting
  2. do not delete rows. just insert new rendered rows after some row, having done some operations with them (initialization and etc.) before inserting
  3. on event "onclick" i need to get row data: var rowData = $row.view().data;

when i use render: var $rows = $(compiledTmpl.render(dataArray, helperObj)); i can do anything with rendered rows. i can initialize them and insert them after some row. but when event "onclick" raise, i get empty data (rowData). why?

when i use link: compiledTmpl.link($table, dataArray, helperObj) i can not get rendered rows. why? i can not initialize them and insert them after some row. but when event "onclick" raise, i get not empty data (rowData).

how to be in my cases?

UPDATE: https://jsfiddle.net/chdcfsnv/4/

UPDATE 2: shortly (and simplistically), i want to get rendered new rows. add them after the existing row. later i need to be able to get linked row data. other functionality i do not need so far.


Solution

  • JsRender render() method will simply render a template against data and return a string (typically HTML markup you want to insert into the DOM). You are then responsible for inserting the resulting markup into the DOM. Of course you can modify the markup with code before you insert it. But JsRender does not know about the HTML DOM, and does not do data-binding. If you click on the element, the element will not have any knowledge of the data that it was rendered from in JsRender. (For that you would need to design your own data-binding, e.g. by inserting data IDs into the markup before it gets added to the DOM).

    But JsViews does do data-binding. For it to work you must use the link() method so that JsViews inserts the rendered template into the DOM, along with data-binding information that it creates. Then you can use $(elem).view().data to get back to the data, or you can make observable changes to the data, and have JsViews dynamically make the data-driven changes to the HTML based on your declarative data-linked templates.

    But you can't have it both ways. If you want to use code to modify the markup before it gets inserted in the DOM then you must use the render() method, and insert in the DOM yourself, but you will not have any automatic data binding, and $(element).view() will not allow you to magically get back to the data.

    On the other hand, if you want JsViews data-binding, and want to use view() to get back to the data, then you must use the declarative approach to define your HTML based on the data. You can't modify the HTML strings using code and expect data-binding to continue to work. The examples here show how to use JsViews for a similar case to the one you are trying to build in your jsfiddle: http://www.jsviews.com/#jsvplaying

    Additional comments

    In response to your questions below in the comments.

    jQuery Templates is equivalent to JsRender render method in that both of them allow you to insert after an existing element. But neither of them provide data-binding or the view().data functionality to get back to data.

    JsViews link method does allow you to insert after an existing element - but you need to place your container element (e.g. a <tbody>) or a placeholder element there, as target for the link() insertion. See http://borismoore.github.io/jsviews/demos/step-by-step/01_rendering-and-linking.html.

    If you need to get the inserted html elements, after an observable change has happened, you have a few options:

    1. Insert ids in the elements, or use index, and simply use a jQuery selector.
    2. Listen to JsViews onAfterChange view events
    3. Listen to JsViews "jsv-domchange" HTML DOM events

    I created a jsfiddle here which shows all three: http://jsfiddle.net/BorisMoore/eonp89gj/