This is a migrated thread and some comments may be shown as answers.

Prevent Grid SignalR (Server Side Paging) To Append Another Client Modified Rows

8 Answers 185 Views
Grid
This is a migrated thread and some comments may be shown as answers.
infocho
Top achievements
Rank 1
infocho asked on 04 Oct 2016, 08:41 AM

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

Sort by
0
Stefan
Telerik team
answered on 06 Oct 2016, 10:52 AM
Hello ,

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
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
 
0
infocho
Top achievements
Rank 1
answered on 06 Oct 2016, 01:56 PM
Hi Stefan,

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,
0
T. Tsonev
Telerik team
answered on 10 Oct 2016, 03:41 PM
Hello,

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
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
 
0
infocho
Top achievements
Rank 1
answered on 11 Oct 2016, 07:33 AM

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,

0
infocho
Top achievements
Rank 1
answered on 11 Oct 2016, 09:07 AM

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,

0
infocho
Top achievements
Rank 1
answered on 11 Oct 2016, 09:33 AM

Hi, perhaps the best solution is check serverPaging:

...
    this._updatePristineForModel(target, item);
} else if (!this.options.serverPaging) {
    this.pushCreate(item);
}

Kind Regards,

0
Rosen
Telerik team
answered on 12 Oct 2016, 10:33 AM

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
 
Get started with Kendo UI in days. Online training courses help you quickly implement components into your apps.
 
0
infocho
Top achievements
Rank 1
answered on 12 Oct 2016, 11:04 AM

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,

Tags
Grid
Asked by
infocho
Top achievements
Rank 1
Answers by
Stefan
Telerik team
infocho
Top achievements
Rank 1
T. Tsonev
Telerik team
Rosen
Telerik team
Share this question
or