On Thu, Jul 11, 2013 at 5:22 PM, Martin Grigorov <[email protected]>wrote:

>
>
>
> On Thu, Jul 11, 2013 at 4:48 PM, Sven Meier <[email protected]> wrote:
>
>> Hi,
>>
>>
>> >The idea with plain JS solution I cannot visualize in my head yet.
>>
>> EventDelegatingBehavior is just a collector of JavaScript snippets. The
>> actual magic runs in the browser: a custom bubbling of events and
>> delegation to the actual behavior.
>> It should be possible to do this plain with JavaScript:
>>
>>   public class DelegatingAjax implements IAjax {
>>
>>     public ajax(IHeaderResponse response, Component component,
>> AjaxRequestAttributes attributes) {
>>       CharSequence ajaxAttributes = renderAjaxAttributes(**component,
>> attributes);
>>
>> response.render(**OnDomReadyHeaderItem.**forScript("Wicket.Event.***delegate*("
>> + ajaxAttributes + ");");
>>     }
>>   }
>>
>> This would be page-global though.
>
>
> This is an important detail!
> I'll consult with my frontend colleagues but so far I don't see problems.
>

And they say this is a bad idea.
jQuery.live() (deprecated in 1.7.0) did the same, bind on document, and it
was slow.
See http://api.jquery.com/live/
Also see
http://www.ultimatewebtips.com/why-jquery-live-is-a-bad-option-to-use/


>
> For every delegated component we can set special CSS class, e.g.
> 'wicket-delegated'.
> The binding will be: $(document).on('click', '.wicket-delegated',
> function(event) {....})
> i.e. we will take advantage of jQuery delegation/live support.
> This way even newly added items in the repeaters will be automatically
> supported.
>
>
>>
>>
>> Sven
>>
>>
>>
>> On 07/11/2013 03:40 PM, Martin Grigorov wrote:
>>
>>> On Thu, Jul 11, 2013 at 4:30 PM, Nick Pratt <[email protected]> wrote:
>>>
>>>  I think this is great - we have some tables now with a ton of JS events
>>>> on
>>>> the child elements.  Just to clarify, will this make the rendered page
>>>> smaller since there will only be a single JS handler for the event for
>>>> the
>>>> container rather than N JS handlers?
>>>>
>>>>  At the moment all attributes for an inner element are preserved.
>>> 'e' (the event name), 'c' (the component markup id), pd (prevent
>>> default),
>>> sp (stop propagation) can be removed because they are not really used.
>>> But every inner element can have its own call listeners, form submitters
>>> can also have custom settings ('f', 'sc', 'mp', 'm'), so I think they
>>> have
>>> to be preserved.
>>> If you look in #updateAjaxAttributes() for your ajax behaviors in your
>>> table cells you will probably notice that they have their own attributes.
>>>
>>>
>>>  Making it switchable (I think how Sven suggested) would be an
>>>> improvement -
>>>> we could leave it off by default, but provide a simple switch on a
>>>> per-container (or per-app) basis that would allow the dev to choose.
>>>>
>>>>  Yes, it looks as an improvement.
>>> Moving the current code to such implementation is easy.
>>> The idea with plain JS solution I cannot visualize in my head yet.
>>>
>>>
>>>  Regards
>>>>
>>>> Nick
>>>>
>>>> On Thu, Jul 11, 2013 at 4:59 AM, Martin Grigorov <[email protected]
>>>>
>>>>> wrote:
>>>>> Hi,
>>>>>
>>>>> At https://github.com/apache/**wicket/compare/event-**
>>>>> delegating-behavioryou<https://github.com/apache/wicket/compare/event-delegating-behavioryou>
>>>>> may see the diff between master and event-delegating-behavior branches.
>>>>>
>>>>> The latter provides a new AjaxEventBehavior (AEB) -
>>>>>
>>>> EventDelegatingBehavior
>>>>
>>>>> (EDB), that suppresses the JS event binding for all AjaxEventBehaviors
>>>>>
>>>> for
>>>>
>>>>> a given event type (click, submit, change, ...) in the children
>>>>>
>>>> components
>>>>
>>>>> of the host component of EDB.
>>>>>
>>>>> How EDB works:
>>>>>
>>>>> - until now AjaxEventBehavior#renderHead() renders ondomready header
>>>>> item
>>>>> with JS snippet like:
>>>>> Wicket.Ajax.ajax(**attributesObject);
>>>>> In the new branch there is a check if some parent has EDB for the event
>>>>> type of this AEB, and if there is such then the AEB "donates" its
>>>>> attributes to the EDB.
>>>>>
>>>>> - EventDelegatingBehavior#**getCallbackScript() renders :
>>>>> Wicket.Event.delegate('**edbComponentMarkupId', 'eventType',
>>>>> edbAttributes,
>>>>> childrenAttrsMap);
>>>>>
>>>>> - when a delegated component fires its event (e.g. the user clicks on
>>>>> an
>>>>> AjaxLink) the event is handled by EDB's event handler. It extracts the
>>>>> markupId of the inner HTML element and fires Wicket.Ajax.Call with the
>>>>> specific attributes for the extracted inner element.
>>>>>
>>>>> Pros:
>>>>>
>>>>> - simple to use - just add EDB to a container component around your
>>>>> Ajax
>>>>> heavy component (e.g. repeater with many Ajax behaviors). See the demo
>>>>>
>>>> app
>>>>
>>>>> at 
>>>>> https://issues.apache.org/**jira/browse/WICKET-5267<https://issues.apache.org/jira/browse/WICKET-5267>
>>>>>
>>>>> -  faster JS execution
>>>>> -- faster execution of the domready handler because there is just one
>>>>> binding instead of N
>>>>> -- faster reaction because the browser finds the event handler much
>>>>>
>>>> faster.
>>>>
>>>>> I wasn't able to prove this with numbers because there is no way to
>>>>>
>>>> detect
>>>>
>>>>> the 'start time', i.e. when the user makes the action. With JS the
>>>>>
>>>> earliest
>>>>
>>>>> point is when the browser has already looked up the event handler.
>>>>> Chrome Dev tools (timeline, profiling, pagespeed) don't help too. So my
>>>>> reference that it is faster are the articles in the web and a use case
>>>>> in
>>>>> our application.
>>>>>
>>>>> Cons:
>>>>>
>>>>> - AEB#renderHead() needs to check whether there is EDB up in the
>>>>>
>>>> hierarchy
>>>>
>>>>> to be able to decide what to do.
>>>>> This is ugly, I agree. But I see no other solution that will preserve
>>>>> the
>>>>> transparent usage of something like EDB and will not require a major
>>>>> rewrite of user applications to be able to use event delegation.
>>>>> -- there are some optimizations to lower the impact of the new checks:
>>>>> --- a new setting (IAjaxSettings#**useEventDelegation) - a global
>>>>> property
>>>>> that prevents visiting the parent components and their behaviors for
>>>>> all
>>>>> apps which do not use EDB
>>>>> --- when EDB is bound it registers a metadata for its event type in the
>>>>> page instance. This prevents visiting all behaviors of all parent
>>>>> components
>>>>>
>>>>>
>>>>> I have no more ideas how to further optimize it.
>>>>>
>>>>> Any feedback is welcome! Even if you have a completely different idea
>>>>> how
>>>>> to implement this functionality.
>>>>>
>>>>> Thanks for reading!
>>>>>
>>>>>
>>
>

Reply via email to