简体   繁体   中英

Reference to “this” lost when using dojo aspect around a GridX tree

I am trying to use an around aspect for the expand function of a GridX 's tree.

The simplified code goes like:

var myGrid = ...; // features a tree
var myConditional = ...; // some boolean


dojo.aspect.around(myGrid.tree, "expand", function(original) {
    return function(id, skip) {
        // TODO check the conditional and decide whether 
        // to return the deferred function as is, or 
        // return a function that does nothing but log into the console
        var deferred = original(id, skip);
        return deferred;
    };
});

Unfortunately, the invocation of dojo aspect as is (ie without any check for my conditional, etc.) is problematic.

Once the expando is clicked, an error is thrown in the console:

Uncaught TypeError: t.isExpanded is not a function

... pointing at the body of the GridX tree module's expand original function:

var d = new Deferred(), t = this;
if(!t.isExpanded(id) && t.canExpand(id)){ // here

Clearly my interpretation of how aspect around works is mistaken, and the scope of t becomes the Window object instead of the tree itself.

I am hoping there's a quick fix/workaround I can use?

Clarification on my actual purpose

Under certain circumstances, the back-end queried by the store underlying the grid will be unreachable for a short amount of time. The way things are implemented, expanding on nodes of the tree will query the back-end. During the very short window while the back-end is unavailable (which I can easily know from the front-end code), I'd like to ignore clicks on the expandos).

Try to bind tree instance to your function. Something like this:

var myGrid = ...; // features a tree
var myConditional = ...; // some boolean

const condExpand = function(id, skip) {
        var deferred = original(id, skip);
        return deferred;
    }.bind(myGrid )


dojo.aspect.around(myGrid.tree, "expand", function(original) {
    return condExpand
});

I'm not sure about where a particular context is lost in your case, but you can play with this to make it work for you.

Update:

Tried to reproduce situation. Below is working example:

    const testObject = {    
      isNumeric: function(number) {
        return typeof number === "number"
      },
      testMethod: function() {
        console.log('testMethod', this)
        console.log("Is 5 a number: ", this.isNumeric(5))
      }
    }

    const aroundFunc = function(originalTestmethod){
        return function(method, args){
          // doing something before the original call
          console.log("Before", this)

          //Here context still corect. 
          //So bind it to passed here original method:

          var deferred = originalTestmethod.bind(this)(method, args)


          // doing something after the original call
          console.log("After")
          return deferred;

        }
      }

require(['dojo/aspect'], function(aspect) {
   aspect.around(testObject, "testMethod", aroundFunc)  
   testObject.testMethod()  

})

JS Fiddle

I found a "solution" that seems absolutely barbaric, but works for me.

Hopefully someone has a better idea, possibly using dojo/aspect.

I've literally copypasted the Tree.js module's code into my own implementation, only adding my own condition:

myGrid.tree.expand = function(id, skipUpdateBody)  {
    var d = new dojo.Deferred(),
        t = this;
    // added my condition here
    if ((!t.isExpanded(id) && t.canExpand(id)) && (myCondition)) {
        // below code all original
        t._beginLoading(id);
        t.grid.view.logicExpand(id).then(function(){
            dojo.Deferred.when(t._updateBody(id, skipUpdateBody, true), function(){
                t._endLoading(id);
                d.callback();
                t.onExpand(id);
            });
        });
    }else{
        d.callback();
    }
    return d;
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM