sebfz1 / wicket-jquery-ui

jQuery UI & Kendo UI integration in Wicket
http://www.7thweb.net/wicket-jquery-ui/
Other
93 stars 58 forks source link

KendoUI Scheduler / loads/requests schedules twice on navigation #239

Closed Patrick1701 closed 3 years ago

Patrick1701 commented 8 years ago

Hi Sebastien, when navigating the scheduler, sometimes the schedules get read twice.

It seems the navigate event callback has something todo with that. Removing the code

        // events //
        this.setOption("navigate", this.onNavigateAjaxBehavior.getCallbackFunction());

in onConfigure(Component) of ScheudlerBehavior fixes it.

But I'm not able to find out why. I don't see any double bindings or something. Perhaps, reading the datasource internally also fires an navigation event? Not sure...

best regards Patrick

Patrick1701 commented 8 years ago

Strange... my attempt to fix this (until you have a solution) by a custom override did not work.

    @Override
    public JQueryBehavior newWidgetBehavior(String selector)
    {
        return new SchedulerBehavior(selector, this.getSchedulerEventFactory(), this) {

            private static final long serialVersionUID = 1L;

            // Properties //

            @Override
            protected CharSequence getDataSourceUrl()
            {
                return MyScheduler.this.getCallbackUrl();
            }

            @Override
            protected ResourceListModel getResourceListModel()
            {
                return MyScheduler.this.getResourceListModel();
            }

            // Events //

            @Override
            protected void onConfigure(SchedulerDataSource dataSource)
            {
                MyScheduler.this.onConfigure(dataSource);
            }

            @Override
            protected JQueryAjaxBehavior newOnNavigateAjaxBehavior(IJQueryAjaxAware source) {
                return new JQueryAjaxBehavior(source) {
                    private static final long serialVersionUID = 1L;

                    @Override
                    public String getCallbackFunction(){
                        return "function(){ }";
                    }

                    @Override
                    protected JQueryEvent newEvent() {
                        return null;
                    }
                };
            }
        };
    }

Now, I don't get any request to the datasource on navigate.

Patrick1701 commented 8 years ago

Ok, got it...

Scheduler.onNavigate() also calls a refresh(). So the datasource.read() js is called twice.

Do you remember, why onNavigate() also calls refresh()?

Patrick

sebfz1 commented 8 years ago

Nope, that's logical that navigate event calls #read. I don't rememeber a reason why I specifically called #refresh. I need to find the commit msg, maybe it can help...

Patrick1701 commented 8 years ago

Now I try to fix it temp. by overriding

    @Override
    public void onNavigate(AjaxRequestTarget target, SchedulerViewType view) {
        target.appendJavaScript(String.format("var $w = %s; if ($w) { $w.dataSource.read(); }", this.widget()));
    }

So only the javascript read() get called, and I still get 2 requests...

Very confusing...

sebfz1 commented 8 years ago

Can you override as a noop method (empty body) ?

Patrick1701 commented 8 years ago

Then no datasource read occurs, at all. (except the first time, when the page renders the scheduler)


Currently I try to debug via FireBug, but I'm not able to see, where the double-call to the read function comes from. In eclipse, it would be easy to walk the stack upward. :-D

sebfz1 commented 8 years ago

I knew there was a reason ;)

Patrick1701 commented 8 years ago

Currently, I think it as something todo with the success() call.

First call... first_read_request

Second call... second_read_request

Patrick1701 commented 8 years ago

I give up...

Here some researches... maybe you have an idea...

http://www.telerik.com/forums/controller-action-hit-twice-when-calling-read

http://stackoverflow.com/questions/24803051/update-kendo-ui-scheduler-datasource-with-remote-data-javascript

http://stackoverflow.com/questions/17180071/c-sharp-mvc-controller-called-twice

kind regards Patrick

sebfz1 commented 8 years ago

Hi Patrick,

Thanks again for these investigations! I will look at this next week...

Best regards, Sebastien

Patrick1701 commented 8 years ago

Hi Sebastien, any news here?

Thanx Patrick

sebfz1 commented 8 years ago

Well, I am unfortunately late on several topics. Thanks for the reminder, I will try to have a look this week (I know, that's already what I wrote last time ;) )

Patrick1701 commented 8 years ago

Ping! :-)

sebfz1 commented 8 years ago

Damned !!! I'm so sorry about the delay ! :( But I did not gave up ! :)

Patrick1701 commented 3 years ago

Hi Sebastien, years ago... :-) I did some deeper investigation, due to massiv performance issues on client-side rendering, when having an open week-view with many many resources and events.

I opened a ticket at telerik support. Currently, I assume, it is a bug in KendoUI.

As the KendoUI documentation says, when using a javascript function as read-callback method it is necessary to call success() or error(), to let the datasource know, there was a successfull read.

Internally, kendo triggers some events... also a change-event, which is also observed by the datasource, so the datasource does a second call. Why this behavior do not ends up in a infinite loop... hmm... I don't know it. This is just too deep of internal KendoUI code.

So, when I get feedback by telerik, I will let you know.

best regards :-) Patrick

sebfz1 commented 3 years ago

Thanks Patrick, I never understood why this happened! Hope you will get an answer! :)

Patrick1701 commented 3 years ago

A little preview... It seems it is a problem, when dequeing the request. This happens on Success-Call for the readCallBack-Function, you use. Internally, kendo checks for a pending request, and if so, it queues the request again. You can see it at second the screenshot above... but I have never really recognized this. Quite blind. :-) A colleque of mine saw it yesterday. I reported this to telerik also... I'm still waiting for feedback.

sebfz1 commented 3 years ago

I am (sooooo) glad to tell you it is fixed!

Since the beginning of this issue, we have been focused on why there is a double call. I came to the same observations as you and your colleague. I couldn't figure out why the Scheduler seemed to call datasource#read on its own and only after the second prev/next navigation click. To me whether it should always handle the read or never. But as it does not handle the read at the first prev/next navigation click, I implemented the callback logic on-navigate (otherwise no events are loaded as you noticed previously). After hours - again - of debugging, the idea popped in my mind: "Is there a way to tell the Scheduler it has to manage the remote datasource 100% on its own?". Well, in the Grid (DataTable) implementation, we can force the behavior by setting the serverFiltering flag to true. In the case of the Scheduler there is no filter, so nothing to filter by. It didn't made sense to activate the option (and I never saw an example with the Scheduler and the Remote DataSource where they activated the option). But guess what... It effectively force the scheduler to handle the remote datasource on its own while navigating! Hence calling refresh on-navigate is not needed anymore, hence there is no double calls anymore!

I have some cleanup to do, and I will release the fix by today!

Patrick1701 commented 3 years ago

Hi Sebastien, this sounds great. I also brainstormed about the serverFiltering Flag, but wasn't sure about that. :-D

Could you please provide a bugfix Version v8.10.1? Currently we are not able to upgrade higher due to our KendoUI pro license. We currently sticking at Kendo 2020 JS Versions...

best regards Patrick

sebfz1 commented 3 years ago

You can easily apply the fix on your own:

new Scheduler("scheduler", newSchedulerModel(), options) {

    @Override
    protected void onConfigure(SchedulerDataSource dataSource)
    {
        super.onConfigure(dataSource);

        dataSource.set("serverFiltering", true);
    }

    @Override
    public void onNavigate(AjaxRequestTarget target, SchedulerViewType oldView, SchedulerViewType newView)
    {
        // noop (will cancel the refresh)
    }
sebfz1 commented 3 years ago

8.12.0 has been released. I will try to provide a patch version for 8.10.x, you can use the temporary fix above in the meantime...

Patrick1701 commented 3 years ago

I will try to provide a patch version for 8.10.x

@sebfz1 Ping :-)

sebfz1 commented 3 years ago

Released 8.10.1

Patrick1701 commented 3 years ago

Hi Sebastien, I'm currently working on the Scheduler again... and I still had some strange behaviors when changing the view. (I remember, I told you something via mail.... have a look please)

Currently, we still had to call refresh() when changing a view in order to have the scheduler displaying the correct results. What I've seen is, a databound callback is still called twice, and I think its the refresh call.

I manually call target.appendJavaScript(String.format("var $w = %s; if ($w) { $w.dataSource.read(); }", this.widget()));

As you can see, there is no refresh() anymore. Just a dataSource.read()...

Do you know, or could you confirm, that the dataSource.read() call, somehow by default calls a refresh() which fires the dataBound-Event?

kind regards Patrick