MVVM function calls, value of "this" different for click event vs console call

3 posts, 0 answers
  1. Sam
    Sam avatar
    3 posts
    Member since:
    Feb 2018

    Posted 19 Nov 2018 Link to this post

    I'm setting up a fairly complex (for us) ViewModel for report generation, which will have multiple nested fields that need to call functions on each other and on parents and children.  I'd like to be able to test it in the browser console by calling the VM functions directly, but I've found that "this" is different in the functions depending on whether they've been called by a data-bind click event, vs being called directly from the console command line.

    Here's a Dojo setup showing the problem: https://dojo.telerik.com/ucalOzoW

    Open the browser console and click Run in Dojo.  You'll see it call testVm.funcTopLevel() with no problem.  Then it calls testVm.fields.field1.funcNested() as you would from the console, and it works as I would expect, where this.id refers to the id property of the object at that level ("idField1"), and this.parent().parent().id refers to the id property of the parent object ("idTopLevel").

    But then when you click the "call funcNested" button, "this" now refers to the top-level VM object, and this.parent() is undefined.  I'm assuming there's something going on with how the functions are being bound to "this" in MVVM when called from a click event...

    I'd like for the function's behavior and scope to be the same no matter if it's called from the console or from a click event, is there any way to do that?  Or is there something I'm missing?

    Thanks!

  2. Sam
    Sam avatar
    3 posts
    Member since:
    Feb 2018

    Posted 20 Nov 2018 in reply to Sam Link to this post

    I found a brute-force workaround that I'm using until I find some other way.  I put this line at the top of my nested functions:

    var self = this; while (typeof self.parent() !== 'undefined') self = self.parent();

    Then I use "self" instead of "this" everywhere in the function, and I know it always refers to the top-level VM object, no matter where the function is being called from.  Fortunately, performance isn't an issue (yet, anyway), but that would be a potential concern about doing it this way, not to mention it seems inelegant.

  3. Ivan Danchev
    Admin
    Ivan Danchev avatar
    2080 posts

    Posted 21 Nov 2018 Link to this post

    Hello Sam,

    An alternative approach in this scenario involving nested fields would be to use a template through which to specify the context. Here's a modified version of the original dojo example. this.id and this.parent().parent().id values are identical when the method is called initially and subsequently on clicking the call funcNested button.

    Regards,
    Ivan Danchev
    Progress Telerik
    Get quickly onboarded and successful with your Telerik and/or Kendo UI products with the Virtual Classroom free technical training, available to all active customers. Learn More.
Back to Top