English 中文(简体)
Is it possible to invoke the jQuery.data() method within a jQuery template?
原标题:

I m using the jQuery template plug-in (official jquery-tmpl plugin) to build up a an HTML list. The template basically defines <li> elements and looks something like this:

<script id="item-display-template"> type="text/html">
  <li>
    <div class="item-display-container">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a onclick="editRow();">Edit This Item</a>
    </div>
  </li>
</script>

Each item in the resulting list will have an Edit This Item link that will invoke an editRow function. I need to be able to provide this function with the primary key (id) of the database record for the item being edited. The id is included in the JSON being bound to the template. My first thought was to do this with the Edit This Item link:

<a onclick="editRow(${Id});">Edit This Item</a>

I think that will work, but I m not sure that this is the "right way".

Is it possible to invoke the jQuery.data() method within the template to attach the Id value to one of the DOM elements as the template is being rendered?

最佳回答

Change your template to be something like:

<script id="item-display-template" type="text/html">
  <li>
    <div class="item-display-container" data-itemid="${Id}">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a class="editrow">Edit This Item</a>
    </div>
  </li>
</script>

By placing the id on the div.item-display-container you make it very easy to add other functionality that can easily access that same id, say like a delete link.

Then on the <ul> element you are inserting these <li> element in to do this:

$( ul ).delegate( .editrow , click ,function(e) {
    e.preventDefault();
    var id = parseInt($(this).parents( .item-display-container ).attr( data-itemid ), 10);
    editRow(id);
});
问题回答

I would use a data attribute, like this:

<script id="item-display-template"> type="text/html">
  <li>
    <div class="item-display-container">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a class="edit" href="#" data-id="${Id}">Edit This Item</a>
    </div>
  </li>
</script>

Then a .live() or .delegate() handler, like this:

$("a.edit").live("click", function() {
  var id = $(this).attr("data-id");
  //use the id
});

Or .delegate():

$("#myUL").delegate("a.edit", "click", function() {
  var id = $(this).attr("data-id");
  //use the id
});

As a side note: In jQuery 1.4.3+ coming out later this week, you can use .data() like this:

var id = $(this).data("id");
//or:
var id = $.data(this, "id");

It ll fall back to the data-id attribute to get a value if there isn t one in it s data collection.

No, you can t do that, but you could stash the "id" in some HTML attribute — like, say, the "id" attribute.

(Well actually you could have the template generate in-line Javascript blocks to do it, but that seems terribly ugly.)

Rather than using old-fashioned "onclick" to bind your event handlers, you could give the <a> elements the "id" value (with some alpha prefix, if the "id" value is numeric) and also a "class" value. Then, after expanding the template from your jQuery code, you could bind event handlers. Alternatively you could pre-bind event handlers with .delegate() (edit like in @Nick s answer.)

<script id="item-display-template"> type="text/html">
  <li>
    <div class="item-display-container">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a id="id_${Id}" class="link-for-edit">Edit This Item</a>
    </div>
  </li>
</script>

var eventEdit = function(ev) {
    //...
    var id = $(this).attr( id ).split( _ );
};

var items = $( #item-display-template ).tmpl(data);

$(items).find( a.link-for-edit ).bind( click , eventEdit);
$(items).appendTo( ul );

jQuery templates has jQuery.tmplItem() function. Using this, you can access the data object you have used to render the template. So it s not necessary to duplicate the data at the DOM level. You can use it like this:

<script id="item-display-template" type="text/html">
  <li>
    <div class="item-display-container">
        <p>${SomeData1} .... ${SomeData2} etc....</p>
        <a class="editrow">Edit This Item</a>
    </div>
  </li>
</script>

Then in the "Edit..." click handler you access template s underlaying data to get the Id value:

$( ul ).delegate( .editrow , click ,function(e) {
    e.preventDefault();
    var id = $(this).tmplItem().data.Id;
    editRow(id);
});

JQuery templates already solve this problem for you with the tmplItem function. You can use the clicked element to associate the data that it is bound to:

$("#item-display-template").tmpl(clientData).appendTo("ul"); 

$("li a").click(function() {
    var tmplItem = $(this).tmplItem();
    alert(tmplItem.data.id);
});

See the full working example I did here

....and a related question here for another example.





相关问题
getGridParam is not a function

The HTML: <a href="javascript:void(0)" id="m1">Get Selected id s</a> The Function: jQuery("#m1").click( function() { var s; s = jQuery("#list4").getGridParam( selarrrow )...

selected text in iframe

How to get a selected text inside a iframe. I my page i m having a iframe which is editable true. So how can i get the selected text in that iframe.

jQuery cycle page with links

I am using the cycle plugin with pager functionality like this : $j( #homebox ) .cycle({ fx: fade , speed: fast , timeout: 9000, pager: #home-thumbs , ...

jquery ui dialog opens only once

I have a button that opens a dialog when clicked. The dialog displays a div that was hidden After I close the dialog by clicking the X icon, the dialog can t be opened again.

jConfirm with this existing code

I need help to use jConfirm with this existing code (php & Jquery & jAlert). function logout() { if (confirm("Do you really want to logout?")) window.location.href = "logout.php"; } ...

Wrap text after particular symbol with jQuery

What I m trying to do, is wrap text into div inside ll tag. It wouldn t be a problem, but I need to wrap text that appears particularly after "-" (minus) including "minus" itself. This is my html: &...

热门标签