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

9 posts, 0 answers
  1. infocho
    infocho avatar
    8 posts
    Member since:
    Oct 2010

    Posted 04 Oct Link to this post

    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?

  2. Stefan
    Admin
    Stefan avatar
    264 posts

    Posted 06 Oct Link to this post

    Hello SIlvia,

    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.
     
  3. Kendo UI is VS 2017 Ready
  4. infocho
    infocho avatar
    8 posts
    Member since:
    Oct 2010

    Posted 06 Oct in reply to Stefan Link to this post

    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,
  5. T. Tsonev
    Admin
    T. Tsonev avatar
    2770 posts

    Posted 10 Oct Link to this post

    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.
     
  6. infocho
    infocho avatar
    8 posts
    Member since:
    Oct 2010

    Posted 11 Oct in reply to T. Tsonev Link to this post

    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,

  7. infocho
    infocho avatar
    8 posts
    Member since:
    Oct 2010

    Posted 11 Oct Link to this post

    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,

  8. infocho
    infocho avatar
    8 posts
    Member since:
    Oct 2010

    Posted 11 Oct in reply to infocho Link to this post

    Hi, perhaps the best solution is check serverPaging:

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

    Kind Regards,

  9. Rosen
    Admin
    Rosen avatar
    3234 posts

    Posted 12 Oct Link to this post

    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.
     
  10. infocho
    infocho avatar
    8 posts
    Member since:
    Oct 2010

    Posted 12 Oct in reply to Rosen Link to this post

    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,

Back to Top
Kendo UI is VS 2017 Ready