0

我的模板的 HTML 中有一个按钮。我怎样才能让它在当时渲染的对象上调用一个函数?

我意识到this当时指的是按钮。但是我怎么称呼这个人呢?

完整代码:JS Fiddle

模板

<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();
}
4

1 回答 1

2

为什么这不起作用

这是不可能的,因为从 HTML 附加事件处理程序需要对处理程序函数进行序列化(即以源代码形式)。没有真正的方法可以在 JavaScript 中序列化函数,即使你可以,也有另一个亮点:在函数内部作为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's .data)并从点击处理程序中引用它;处理程序本身可以被委派以保存函数并允许动态添加更多呈现的模板。

例如:

HTML 模板本身根本不附加任何处理程序。

添加渲染模板时,使用.data将其与人员对象相关联,并执行某些操作以将其标记为从 DOM 角度可见的人员相关联。这可以像添加data-person属性(或 CSS 类)一样简单:

$("#peopleWrapper").append(
  $(template(this)).data("Person", this).attr("data-person", ""));

将委托处理程序附加到识别按钮单击的 DOM,并从单击的元素开始,找到关联的人员对象并调用happyBirthday方法:

$("#peopleWrapper").on("click", "[data-person] button", function() {
    $(this).closest("[data-person]").data("Person").happyBirthday();
});

看到它在行动

于 2013-08-16T08:27:31.527 回答