kendo.data.Model (ObservableObject) set method and race conditions with the change method

6 posts, 0 answers
  1. Dave
    Dave avatar
    15 posts
    Member since:
    Aug 2013

    Posted 15 Jul 2014 Link to this post

    I'm trying to set values on a model object (kendo.data.Model, which is an ObservableObject in the covers according to the documentation on the set property), but I'm in a race condition with the change event.  

    In other words, I try setting a value and then mark it as "not dirty" so that it doesn't get posted back to the server, but I can't.

    For example, if I do this in my success method after a POST to create an object:
    someItem.set('anyFieldUpdateByTheServer', data.anyFieldUpdateByTheServer);
    someItem.set('dirty', false);  

    I will immediately get a PUT because I'm updating the field.  

    Is there a way of setting properties on an object, WITHOUT causing a postback to the server.  I'm assuming that I'm supposed to use 'set' to update properties on Model objects since things don't always work on the view if you forget to do this.   Is there perhaps a way of setting something and marking it as "not dirty" at the same time?  I'm also having the very same issue with client side properties like calculated amount fields.  They are client side only, but I put them on an kendo.data.Model so that the view updates.  I just don't want them causing post back to the server.
  2. Petyo
    Admin
    Petyo avatar
    2439 posts

    Posted 16 Jul 2014 Link to this post

    Hi David,

    one workaround you may try is to set the first property directly:

    someItem.anyFieldUpdateByTheServer = data.anyFieldUpdateByTheServer;
    someItem.set('dirty', false);

    The set call should trigger the change and post the two fields as expected. 

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  3. Kendo UI is VS 2017 Ready
  4. Dave
    Dave avatar
    15 posts
    Member since:
    Aug 2013

    Posted 16 Jul 2014 in reply to Petyo Link to this post

    Petyo,

    Thank you for your response.  

    I gave it a try turning this code:
    if (Number(lineItem.get('amount')) != total) {
        var wasDirty = lineItem.get('dirty');
        lineItem.set('amount', total);
        lineItem.set('dirty', wasDirty);
        return true;
    }

    into this:
    if (Number(lineItem.get('amount')) != total) {
     var wasDirty = lineItem.get('dirty');
     lineItem.amount = total;
     lineItem.set('dirty', wasDirty);
     return true;
    }

    Afterwards, the amount stopped updating in the UI.

    Dave
  5. Petyo
    Admin
    Petyo avatar
    2439 posts

    Posted 18 Jul 2014 Link to this post

    Hello David,

    this is somewhat expected, as the direct assignment will not trigger the events which in turn update the UI. A thing which may work is to use the other field for a direct assignment (dirty), in case you don't have UI bound to it. 

    If this does not work for your case, you may also try manually triggering the change event after the assignments, although this is not a documented approach:

    lineItem.trigger("change");


    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
  6. Dave
    Dave avatar
    15 posts
    Member since:
    Aug 2013

    Posted 18 Jul 2014 in reply to Petyo Link to this post

    Petyo, 

    I tried this, but it didn't work:
    if (Number(lineItem.get('amount')) != total) {
       var wasDirty = lineItem.get('dirty');
       lineItem.amount = total;
       lineItem.trigger('change');
       lineItem.set('dirty', wasDirty);
       return true;
    }

    I can see the change event firing because I'm monitoring my observable array for changes, but is does NOT update the view.  I'm guessing it's because, unlike the other change events, it does not name the field in the field property, which you do see if you use the set method.
  7. Petyo
    Admin
    Petyo avatar
    2439 posts

    Posted 22 Jul 2014 Link to this post

    Hi David,

    triggering the change event in this way would kind of defeat the purpose of the direct assignment. What I had in mind was something like this:

    if (Number(lineItem.get('amount')) != total) {
       var wasDirty = lineItem.get('dirty');
       lineItem.amount = total;
       lineItem.dirty = wasDirty;
       lineItem.trigger('change', { field: "amount" }); // the event data is needed for the UI
       return true;
    }

    However, In general, these workarounds are not really reliable and work against the MVVM internals. The "cleanest" approach, if possible would be to turn the datasource auto-sync option and call the method manually. 

    Regards,
    Petyo
    Telerik
     
    Join us on our journey to create the world's most complete HTML 5 UI Framework - download Kendo UI now!
     
Back to Top
Kendo UI is VS 2017 Ready