3

我正在使用 SignalR 和 Kendo Scheduler 进行实施。创建新任务时(例如),SchedulerDataSource 传输将连接集线器 ID 作为附加参数发送到服务器:

transport: {
    read: { url: global.web_path + 'Home/Tasks' },
    update: { url: global.web_path + 'Home/UpdateTask', type: 'PUT', contentType: 'application/json' },
    create: { url: global.web_path + 'Home/CreateTask', type: 'POST', contentType: 'application/json' },
    destroy: { url: global.web_path + 'Home/DeleteTask', type: 'DELETE', contentType: 'application/json' },
    parameterMap: function (options, operation) {
        if (operation == "destroy" && options.models) {
            return JSON.stringify({ taskId: options.models[0].Id, callerId: $.connection.hub.id });
        }
        if (operation !== "read" && options.models) {
            return JSON.stringify({ tasks: options.models, callerId: $.connection.hub.id });
        }
    }
},

服务器做它必须做的任何事情,并向除调用者之外的所有其他用户发送通知:

[HttpPost]
public JsonResult CreateTask(List<ScheduledEvent> tasks, string callerId)
{
   ...create task and other stuff

   //broadcast the newly created object to everyone except caller
   var hubContext =     GlobalHost.ConnectionManager.GetHubContext<Notebooks.Hubs.SchedulerHub>();
   hubContext.Clients.AllExcept(callerId).UpdateSchedule(task);

   //return the object to caller
   return Json(task);
}

一旦其他客户端从中心接收到新任务,它就会被添加到 SchedulerDataSource:

hub.client.updateSchedule = function (scheduledEvent) {
   schedulerDataSource.add(scheduledEvent);
}

一切似乎都运行良好,我确实花了一些时间才意识到这种行为:如果客户端打开了调度程序窗口,一旦更新了 schedulerDataSource,这个窗口就会关闭。这是预期的还是我做错了什么?

4

2 回答 2

0

编辑:我刚刚意识到这个问题有多老了,所以你现在可能已经转向其他事情了,或者当时可能不存在 pushCreate 方法。

我认为这可能是它的工作原理,但它似乎应该能够在幕后添加这些事件而无需关闭编辑窗口。您是否尝试过pushCreate 方法?如果这不起作用,因为添加会自动关闭编辑对话框,也许当事件进入时,如果对话框打开,您可以存储新事件,然后在用户关闭编辑对话框时添加它们。

于 2015-03-02T21:20:49.100 回答
0

我的答案现在更老了;)但我今天遇到了同样的问题。

首先,我很确定这确实是预期的行为。您可以在 kendo 源代码中看到调度程序的传输更新和创建方法中关闭编辑器窗口方法的调用。

以下是我为绕过该问题所做的工作。这个想法很简单,当约会修改来自另一个集线器客户端时,防止编辑窗口关闭。

服务器端:修改集线器方法(以更新方法为例)

    public MyAppointmentViewModel Update(MyAppointmentViewModel appointment)
    {
        if (!appointmentService.Update(appointment))
             throw new InvalidOperationException("Something went wrong");
        else
        {
             Clients.Others.PrepareBeforeAddOrUpdateSignal(appointment.Id);
             Clients.Others.Update(appointment);
             return appointment;

        }
    }

在这里,您会看到我们通知所有其他客户(通过 PrepareBeforeAddOrUpdate)我们即将更新一个 appintment。

现在是客户端(例如在 index.cshtml 中)

schedulerHub.client.prepareBeforeAddOrUpdateSignal = function(id){ lastModifiedRdvId = id; };
schedulerHub.client.create = function(appointment){ lastModifiedRdvId = 0; }; /* reset the variable for next time */
schedulerHub.client.update = function(appointment){ lastModifiedRdvId = 0; }; /* reset the variable for next time */

function SchedulerEditor()
{
    return $(".k-scheduler-edit-form").data("kendoWindow");
}

var eventBeforeChanges = null;
var lastModifiedRdvId = 0;

function onEditorClose(e) {
    if (eventBeforeChanges != null) {
        if (lastModifiedRdvId > 0 && eventBeforeChanges.Id != lastModifiedRdvId)
            e.preventDefault();
    else {
        var editWin = SchedulerEditor(); /* unbind this callback and use default behavior again */
        editWin.unbind('close', onEditorClose);
    }
}}
function onEditRdv(e) {    
    var editWin = SchedulerEditor();
    if (editWin != null) /*Bind the close event */
        editWin.unbind('close', onEditorClose).bind('close', onEditorClose);

     eventBeforeChanges = e.event;

     /* continue onEditRdv */
}

您在此处看到,当约会 id 不是当前客户端更新的约会 id 时,关闭事件被阻止。

幸运的是,防止关闭事件可以防止在另一个集线器客户端更改一个之后进行某种幽灵约会的烦人行为。

如果我不清楚或代码不够清楚,我很抱歉。如有必要,我可以提供更多信息。

再见

于 2016-08-31T16:24:40.230 回答