Search code examples
asp.net-mvckendo-uisignalrkendo-ui-grid

How to move SignalR connection scripts to the bottom of the page on Kendo UI MVC grid


I have a kendo grid on a view with signalr connection to back end. It is currently working fine, however, I would like to move the script tag to the bottom of the generated page with a razor @section block.

<script>

var dataCollectionHub;
var hubStart;
$(function () {
    dataCollectionHub = $.connection.dataCollectionHub;
    hubStart = $.connection.hub.start();
});

</script>



 @(Html.Kendo().Grid<ViewModel>()
            .Name("grid")
            .Columns(columns =>
            {
                 columns.Bound(p => p.Name);
            })
            .DataSource(
                dataSource => dataSource
                .SignalR()
                .AutoSync(true)
                .Transport(tr => tr
                    .Promise("hubStart")
                    .Hub("dataCollectionHub")
                    .Client(c => c
                        .Read("read")
                        .Create("create")
                        .Update("update")
                        .Destroy("destroy")
                        )
                    .Server(s => s.Read("read")))
                .Schema(schema => schema
                    .Model(model =>
                    {
                        model.Id("Id");
                        model.Field("Id", typeof(int)).Editable(false);
                        model.Field("Name", typeof(string)).Editable(false); 
                    })
                )
            )
)

The problem is that the grid requires the variables to be defined before itself because I get the following error:

Uncaught Error: The "promise" option must be set.
at new init (http://localhost:61683/Scripts/kendo/kendo.all.min.js:31:9317)
at Object.oe.create (http://localhost:61683/Scripts/kendo/kendo.all.min.js:28:13869)
at new init (http://localhost:61683/Scripts/kendo/kendo.all.min.js:27:22769)
at Function.ie.create (http://localhost:61683/Scripts/kendo/kendo.all.min.js:28:14660)
at init._dataSource (http://localhost:61683/Scripts/kendo/kendo.all.min.js:53:11752)
at new init (http://localhost:61683/Scripts/kendo/kendo.all.min.js:51:10176)
at HTMLDivElement.<anonymous> (http://localhost:61683/Scripts/kendo/kendo.all.min.js:26:4691)
at Function.each (http://localhost:61683/Scripts/jquery-1.12.3.js:370:19)
at jQuery.fn.init.each (http://localhost:61683/Scripts/jquery-1.12.3.js:137:17)
at jQuery.fn.init.e.fn.(anonymous function) [as kendoGrid] (http://localhost:61683/Scripts/kendo/kendo.all.min.js:26:4668)

Is there any way to move the script tag to bottom of the grid without breaking it?


Solution

  • What you're probably after is the Deferring-Feature of Kendo UI. Usually, the Scripts are generated immediately and all variables and JavaScript methods must exist during the initialization.

    Update your script:

    @(Html.Kendo().Grid<ViewModel>()
        .Name("grid")
        .Deferred() // Add this to your script
        .....
    

    Then move your script to the page bottom, and right after that, put the line:

    @Html.Kendo().DeferredScripts();
    

    Please note that deferred initialization might have some drawbacks. You might run into some timing issues when you access the Widgets in JavaScript, they will now be initialized later, also you might notice some FOUC effects.