I am unable to get a SignalR grid to update a client properly. When I edit client A I get an update notification in client B, but the grid is not updated.
Chrome reveals some JavaScript errors I am unable to correct:
jQuery.Deferred exception: Cannot read property
'models'
of undefined TypeError: Cannot read property
'models'
of undefined
at init._accept (https:
//localhost/MyApp/Scripts/kendo.all.js:6398:49)
at https:
//localhost/MyApp/Scripts/kendo.all.js:6343:34
at mightThrow (https:
//localhost/MyApp/Scripts/jquery-3.1.1.js:3570:29)
at process (https:
//localhost/MyApp/Scripts/jquery-3.1.1.js:3638:12) undefined
.cshtml
@{
ViewBag.Title = "SignalR";
var sessionId = ViewBag.SessionId;
}
@section Header {
@Styles.Render("~/Content/kendo")
}
@section Scripts {
@Scripts.Render("~/bundles/jqueryval")
@Scripts.Render("~/bundles/kendo")
<
script
src
=
"@Url.Content("
~/Scripts/kendo.modernizr.custom.js")"></
script
>
}
<
script
src
=
"@Url.Content("
~/Scripts/jquery.signalR-2.2.2.min.js")"></
script
>
<
script
src
=
"@Url.Content("
~/signalr/hubs")"></
script
>
<
script
>
var hub = $.connection.trackerHub;
hub.connection.qs = { "sessionid": "@sessionId" };
hub.client.connected = function () { };
var hubStart = $.connection.hub.start();
</
script
>
<
br
/>
@(Html.Kendo().Notification()
.Name("notification")
.Width("100%")
.Position(position => position.Top(0).Left(0))
)
@(Html.Kendo().Grid<
TrackerJob
>()
.Name("Grid")
.Columns(columns => {
columns.Bound(o => o.RoNumber).Title("RO/Arrival").HtmlAttributes(new { @class = "green" }).HeaderHtmlAttributes(new { @class = "green" }).Width(95);
columns.Bound(o => o.IsInStart).Title("START").HtmlAttributes(new { style = "border-bottom-style:dashed;" }).HeaderHtmlAttributes(new { @class = "green" }).Width(110);
// for loop here to create columns with custom headers
columns.Bound(o => o.IsInFinish).Title("FINISH").HtmlAttributes(new { style = "border-left-style:dashed;border-bottom-style:dashed;" }).HeaderHtmlAttributes(new { @class = "green" }).Width(110);
})
.Editable(e => e.Mode(GridEditMode.InCell))
.DataSource(d => d
.SignalR()
.AutoSync(true)
.Events(events =>
events.Push(
@<
text
>
function(e) {
var notification = $("#notification").data("kendoNotification");
notification.success(e.type);
}
</
text
>
)
)
.PageSize(10)
.Transport(t => t
.Promise("hubStart")
.Hub("hub")
.Client(c => c
.Read("read")
.Create("create")
.Update("update")
.Destroy("destroy")
)
.Server(s => s
.Read("read")
.Create("create")
.Update("update")
.Destroy("destroy")
)
)
.Schema(schema => schema
.Model(m => {
m.Id(mo => mo.HeaderId);
m.Field(mo => mo.HeaderId).Editable(false);
})
)
)
)
Hub:
namespace
MyApp.Hubs {
public
class
TrackerHub : Hub {
private
static
Object lockObject =
new
Object();
private
List<TrackerJob> jobs;
public
TrackerHub() {
jobs =
new
List<TrackerJob>();
}
public
List<TrackerJob> Read() {
var jobsAndSession = CurrentSessions[
"A"
]
as
JobsAndSession;
return
jobsAndSession.Jobs;
}
public
void
Update(TrackerJob tj) {
var jobsAndSession = CurrentSessions[
"A"
]
as
JobsAndSession;
var sessionHolder = jobsAndSession.Session;
var departmentCodes = CreateDeptCodesString(tj);
// update remote DB
updateTrackerJob(tj);
Clients.Others.update(tj);
}
public
void
Destroy(TrackerJob tj) {
}
public
TrackerJob Create(TrackerJob tj) {
return
new
TrackerJob();
}
private
void
updateTrackerJob(TrackerJob tj) {
var jobsAndSession = CurrentSessions[
"A"
]
as
JobsAndSession;
List<TrackerJob> updatedJobs =
new
List<TrackerJob>();
var presentJobs = jobsAndSession.Jobs
as
List<TrackerJob>;
updatedJobs = presentJobs.Where(o => o.HeaderId != tj.HeaderId).ToList();
updatedJobs.Add(tj);
jobsAndSession.Jobs = updatedJobs;
lock
(lockObject) {
CurrentSessions[
"A"
] = jobsAndSession;
}
}
private
string
CreateDeptCodesString(TrackerJob tj) {
string
codesString =
string
.Empty;
// generate proper codesString
return
codesString;
}
private
readonly
static
ConnectionMapping<SignalRBase> _connections =
new
ConnectionMapping<SignalRBase>();
public
override
Task OnConnected() {
_connections.Add(CreateConnectionKey(), Context.ConnectionId);
return
base
.OnConnected();
}
public
override
Task OnDisconnected(
bool
stopCalled) {
_connections.Remove(CreateConnectionKey(), Context.ConnectionId);
return
base
.OnDisconnected(stopCalled);
}
public
override
Task OnReconnected() {
if
(!_connections.GetConnections(CreateConnectionKey()).Contains(Context.ConnectionId)) {
_connections.Add(CreateConnectionKey(), Context.ConnectionId);
}
return
base
.OnReconnected();
}
private
SignalRBase CreateConnectionKey() {
// create and return connection key object
}
}
}
There is some information that needs to be retrieved from Session that I'm filling into an accessible Hashtable in my Controller.
I've tried to mimic the GitHub example here as best as I could, but I've run into a wall.
Apologies if I've left out pertinent information...let me know if there's anything else useful I can provide.
Any suggestions about where I've gone wrong?