I have a normal client-side app written mostly in jQuery. I'm using Ractive on one specific page, where it's extremely useful. However, all of the old jQuery events are no longer attached, presumably because the DOM has been re-rendered after Ractive has been inited. I tried setting up the events after Ractive has rendered, but that resulted in some weird behavior, lost DOM elements and stuff. Where can I setup those old jQuery handlers, or is it possible? Is the Ractive rendering happening asynchronously, and if so, is there an event I should be listening to?

I've tried

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

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

and

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

解决方案 2

Ractive renders synchronously, so your second example should work (but the first one definitely won't) - unless the .button element you're targeting is inside a section that isn't being rendered:

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

In this example, if someCondition was falsy, there'd be no DOM element for jQuery to target.

A more idiomatic way to do this with Ractive would be this:

template:

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

code:

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

That way, you never need to worry about whether the element has been rendered or not.

(Bear in mind though that the handler would need to change - this means the ractive instance, and the event object passed to the handler is a Ractive event rather than a native DOM event - to get the native event use event.original.)

If the .button element should be being rendered straight away (i.e. it's not in a falsy section), and jQuery still can't find it after the initial render, then it means you've found an interesting bug... let us know!

其他提示

Beyond Rich's suggestion to use Ractive's event handling (which is most in-line with Ractive's way of doing thing) you can also use the complete option:

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

Rather than fish around for the element, you can declaratively use a decorator to know when the element is created (and destroyed), and be handed a reference to it.. In your template:

<button decorator='initbutton'/>

Then in code:

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', ...) 
            }
        }
    }
});
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top