2

我有一个主要用 jQuery 编写的普通客户端应用程序。我在一个特定页面上使用 Ractive,它非常有用。但是,所有旧的 jQuery 事件都不再附加,大概是因为在 Ractive 启动后 DOM 已经重新渲染。我尝试在 Ractive 渲染后设置事件,但这会导致一些奇怪的行为,丢失 DOM 元素和东西。我在哪里可以设置那些旧的 jQuery 处理程序,或者有可能吗?Ractive 渲染是否异步发生,如果是,是否有我应该听的事件?

我试过了

$('.button').click(someHandler);  // <--- Here

getData(function(data){
    ractive = new Ractive({
        el: '.content',
        template: template,
        data: data
    });
});

getData(function(data){
    ractive = new Ractive({
        el: '.content',
        template: template,
        data: data
    });
    $('.button').click(someHandler); // <--- Also here
});
4

2 回答 2

6

除了 Rich 建议使用 Ractive 的事件处理(这与 Ractive 的做事方式最一致)之外,您还可以使用完整选项:

ractive = new Ractive({
    el: '.content',
    template: template,
    data: data,
    complete: function(){
        $('.button').click(...)

        // or better, use ractive's selector 
        // to limit search to the template.
        // You could use this outside of `complete`
        // as well.
        $( this.find('.button') ).click(...)
    }
});

您可以声明性地使用装饰器来了解创建(和销毁)元素的时间,并获得对它的引用,而不是四处寻找元素。在您的模板中:

<button decorator='initbutton'/>

然后在代码中:

ractive = new Ractive({
    el: '.content',
    template: template,
    data: data,
    decorators: {
        initbutton: function(node){
            var $button = $(node)
            $button.on('click', ...)

            return { teardown: function(){ 
                //if you need to do anything to teardown...
                $button.off('click', ...) 
            }
        }
    }
});
于 2014-02-22T16:44:00.413 回答
3

Ractive 同步渲染,因此您的第二个示例应该可以工作(但第一个示例肯定不会) - 除非.button您要定位的元素位于未渲染的部分内:

{{#someCondition}}
  <button class='button'>click me</button>
{{/someCondition}}

在这个例子中,如果someCondition是 falsy,则 jQuery 将没有 DOM 元素作为目标。

使用 Ractive 执行此操作的更惯用的方法是:

模板:

{{#someCondition}}
  <button on-click='doSomething'>click me</button>
{{/someCondition}}

代码:

ractive = new Ractive({...});
ractive.on('doSomething', someHandler);

这样,您就不必担心元素是否已被渲染。

(请记住,虽然处理程序需要更改 -this表示ractive实例,并且event传递给处理程序的对象是 Ractive 事件而不是本机 DOM 事件 - 才能使用本机事件event.original。)

如果该.button元素应该被立即渲染(即它不在一个 falsy 部分),并且在初始渲染后 jQuery仍然找不到它,那么这意味着你发现了一个有趣的错误......让我们知道!

于 2014-02-21T20:55:54.137 回答