我的模板的HTML中有一个按钮。如何让它在当时渲染的对象上调用函数?
我意识到this
正在引用当时的按钮。但是我怎么称呼这个人?
TEMPLATE
<script type="text/template" id="tpl-person">
<tr>
//...
<td><button onclick="this.happyBirthday()">Birthday</button></td>
</tr>
</script>
JAVASCRIPT
var Person = function(name, age){
//....
this.happyBirthday = function(){
this.age ++;
}
this.render = function(){
var template = _.template($("#tpl-person").html());
$("#peopleWrapper").append(template(this));
}
//constructor
this.name = name;
this.age = age;
this.render();
}
答案 0 :(得分:2)
不可能这样做,因为从HTML附加事件处理程序要求处理函数被序列化(即以源格式)。有no real way在JavaScript中序列化一个函数,即使你可以有另一个showstopper:在函数this
内部是对现有JavaScript对象的引用,这是不可能的,因为再次,你所做的一切确实需要序列化。
一个简单的解决方法是在呈现模板时使用jQuery附加事件处理程序。
考虑到this
的期望值,您可以在任何Person
方法中定义事件处理函数
// $.proxy because otherwise "this" would be the clicked button element
$.proxy(this.happyBirthday, this);
附加点击处理程序非常简单:
var clickHandler = $.proxy(this.happyBirthday, this);
var html = $(template(this));
$("#peopleWrapper").append(html.find("button").click(clickHandler).end());
那就是说,这看起来不是安排事情的好方法。考虑一个不同的建议:将Person
对象附加到呈现的模板(例如通过jQuery的.data
)并从单击处理程序中引用它;可以委派处理程序本身来保存函数并允许动态添加更多渲染模板。
例如:
HTML模板本身根本不附加任何处理程序。
添加渲染模板时,使用.data
将其与person对象关联,并执行某些操作以将其标记为从DOM透视图可见的人员关联。这可以像添加data-person
属性(或CSS类)一样简单:
$("#peopleWrapper").append(
$(template(this)).data("Person", this).attr("data-person", ""));
将委托处理程序附加到DOM,以识别按钮上的点击,并从单击的元素开始,找到关联的person对象并调用happyBirthday
方法:
$("#peopleWrapper").on("click", "[data-person] button", function() {
$(this).closest("[data-person]").data("Person").happyBirthday();
});
<强> See it in action 强>