I am testing
signalR with grid with server side paging/filtering/sorting and work very well. I’d
like to know how prevent adding new rows to other clients when a row is
modified. Example:
User 1 is
on first page while User2 is on the last page. When User 1 modify a row User 2
can see the modified row at end of the grid. I have already tried this:
function notification(e) {
var notification = $("#notification").data("kendoNotification");
notification.success(e.type);
if (e.type == "create") {
e.items.pop();
e.preventDefault();
}
}
The creation operation was not permitted by
grid but the type is always “create” when record was not found on client
datasource. There is something for prevent append of new records?
8 Answers, 1 is accepted
After testing the described scenario I was able to observe the following:
1) When the Grid is edited the e.type is returning "update". Please check the following example:
http://dojo.telerik.com/ALOzE
2) When the user adds a new item it will go on the bottom or top of the current page depending on the createAt property of the Grid. If the item is just edited, it will stay at the same position:
http://docs.telerik.com/kendo-ui/api/javascript/ui/grid#configuration-editable.createAt
In order to further investigate the issue, please provide a fully runnable example that reproduces it.
Regards,
Stefan
Telerik by Progress

Sorry, perhaps i am forgotten to tell you that you must be position on a different page of each web client. When a row is modified, the other clients have not the record modified in them datasouce, so it is added at end.
The http://dojo.telerik.com/ALOzE example is wrong because not use server paging (serverPaging: true is missing in datasource options).
You can use your SignalRLocalHubServerOperations example to test it but remeber to correct update from:
public void Update(ProductViewModel product)
{
productService.Update(product);
Clients.Others.update(product);
}
to:
public void Update(ProductViewModel product)
{
productService.Update(product);
Clients.Others.update(new DataSourceResult
{
Data = new[] { product }
});
}
Regards,
I think this is the expected behavior as the clients don't have sufficient information to determine that the row is not new.
I'll confirm this with my colleagues and get back to you tomorrow. Apologies for the caused inconvenience.
Regards,
T. Tsonev
Telerik by Progress

Hi,
Hub call two distinct events: Clients.Others.update when a record is updated and Clients.Others.create when a record is created. I think is sufficient not add the record on update client callback if data source don’t contains it or add an option for that.
Regards,

Hi,
I have found the problem in pushUpdate function of kendo.data,js:
pushUpdate: function (items) {
if (!isArray(items)) {
items = [items];
}
var pushed = [];
for (var idx = 0; idx < items.length; idx++) {
var item = items[idx];
var model = this._createNewModel(item);
var target = this.get(model.id);
if (target) {
pushed.push(target);
target.accept(item);
target.trigger(CHANGE);
this._updatePristineForModel(target, item);
} else {
this.pushCreate(item);
}
}
if (pushed.length) {
this.trigger('push', {
type: 'update',
items: pushed
});
}
},
If target is not found pushCreate is call, why?. I have removed the "else" part and now work correctly or just as I want. I think the best solution is add an option into datasource configuration or into transport configuration.
Regards,

Hi, perhaps the best solution is check serverPaging:
...
this._updatePristineForModel(target, item);
} else if (!this.options.serverPaging) {
this.pushCreate(item);
}
Kind Regards,
Hello infocho,
Unfortunately, doing such modification will result in a breaking change in the current behavior. The method in question is not used only in the context of the SignalR and others may rely on the behavior you have described.
However, in order to implement the functionality you have described - to not add record if it does not exist in the DataSource, you could implement custom push transport similar to the following:
var
dataSource =
new
kendo.data.DataSource({
// type: "signalr",
"transport"
: {
push:
function
(callbacks) {
hub.on(
"update"
,
function
(result) {
if
(dataSource.get(result.ProductID)) { // check if the record exists
callbacks.pushUpdate(result);
}
});
},
read:
function
(options) {
hubStart.done(
function
(result) {
var data = ["read"];
if (!$.isEmptyObject(options.data)) {
data.push(options.data);
}
hub.invoke.apply(hub, data).done(options.success);
});
hub.on(
"read"
, options.success);
},
update:
function
(options) {
hubStart.done(
function
(result) {
hub.invoke(
"update"
, options.data).done(options.success)
});
hub.on(
"update"
, options.success);
}
},
push:
function
(e) {
var
notification = $(
"#notification"
).data(
"kendoNotification"
);
notification.success(e.type);
},
schema: {
model: {
id:
"ProductID"
}
},
"autoSync"
:
true
});
Regards,
Rosen
Telerik by Progress

Hi,
Thanks you for your solution and for your clarification. I have correct my condition to:
} else if (!(this.options.type == "signalr" && this.options.serverPaging)) {
Best regards,