在围绕 GridX 树使用 dojo 方面时,对 "this" 的引用丢失
Reference to "this" lost when using dojo aspect around a GridX tree
我正在尝试对 GridX
树的 expand
函数使用环绕方面。
简化代码如下:
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;
};
});
不幸的是,dojo 方面的调用原样(即没有对我的条件等进行任何检查)是有问题的。
单击 expando 后,控制台会抛出一个错误:
Uncaught TypeError: t.isExpanded is not a function
...指向GridX树模块的主体expand
原函数:
var d = new Deferred(), t = this;
if(!t.isExpanded(id) && t.canExpand(id)){ // here
显然我对 aspect around 如何工作的解释是错误的,t
的范围变成了 Window
对象而不是树本身。
我希望有一个快速的fix/workaround我可以使用?
澄清我的实际目的
在某些情况下,网格底层商店查询的后端将在短时间内无法访问。事物的实现方式,扩展树的节点将查询后端。在非常短的 window 期间,后端不可用(我可以从前端代码中轻松知道这一点),我想忽略对 expandos 的点击)。
我发现一个 "solution" 看起来绝对野蛮,但对我有用。
希望有人有更好的主意,可能使用 dojo/aspect。
我直接将 Tree.js
模块的代码复制粘贴到我自己的实现中,只添加了我自己的条件:
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;
};
尝试将树实例绑定到您的函数。像这样:
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
});
我不确定在你的案例中哪里丢失了特定的上下文,但你可以尝试一下让它为你工作。
更新:
已尝试重现情况。下面是工作示例:
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()
})
我正在尝试对 GridX
树的 expand
函数使用环绕方面。
简化代码如下:
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;
};
});
不幸的是,dojo 方面的调用原样(即没有对我的条件等进行任何检查)是有问题的。
单击 expando 后,控制台会抛出一个错误:
Uncaught TypeError: t.isExpanded is not a function
...指向GridX树模块的主体expand
原函数:
var d = new Deferred(), t = this;
if(!t.isExpanded(id) && t.canExpand(id)){ // here
显然我对 aspect around 如何工作的解释是错误的,t
的范围变成了 Window
对象而不是树本身。
我希望有一个快速的fix/workaround我可以使用?
澄清我的实际目的
在某些情况下,网格底层商店查询的后端将在短时间内无法访问。事物的实现方式,扩展树的节点将查询后端。在非常短的 window 期间,后端不可用(我可以从前端代码中轻松知道这一点),我想忽略对 expandos 的点击)。
我发现一个 "solution" 看起来绝对野蛮,但对我有用。
希望有人有更好的主意,可能使用 dojo/aspect。
我直接将 Tree.js
模块的代码复制粘贴到我自己的实现中,只添加了我自己的条件:
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;
};
尝试将树实例绑定到您的函数。像这样:
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
});
我不确定在你的案例中哪里丢失了特定的上下文,但你可以尝试一下让它为你工作。
更新:
已尝试重现情况。下面是工作示例:
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()
})