论坛首页 Web前端技术论坛

郁闷!DWR的回调方法没有处理调用上下文问题

浏览 4553 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2007-07-05  
DWR

问题描述

        使用DWR+EXT构建AJAX应用,希望把单个页面的所有javascript函数放在一个叫做XXXController的对象中,这个XXXController可能继承一个抽象基类,包含所有页面都可能使用的通用功能。示例代码如下:

js 代码
  1. function Controller() {   
  2. }   
  3.   
  4. Controller.prototype.init = function()   
  5. {   
  6.     //创建用户树组件   
  7.     this.createUserTree();   
  8. }   
  9.   
  10. //创建用户树组件   
  11. Controller.prototype.createUserTree = function()   
  12. {   
  13.     ServiceProvider.getUsers(this.handleUsers);   
  14. }   
  15.   
  16. /**===============DWR回调函数=======================*/  
  17. Controller.prototype.handleUsers = function(users) {   
  18.     //构建根节点   
  19.     if (this instanceof Object)   
  20.         alert("error");   
  21.     var root = new Ext.tree.TreeNode({   
  22.         id:'root',   
  23.         leaf:false,   
  24.         expanded:true,   
  25.         text:'用户列表'   
  26.     });   
  27.     //添加子节点   
  28.     for (var i = 0; i < users.length; i++)   
  29.     {   
  30.         var node = new Ext.tree.TreeNode({   
  31.             id:users[i].id,   
  32.             leaf:true,   
  33.             text:users[i].name   
  34.         });   
  35.         root.appendChild(node);   
  36.     }   
  37.     //构建树面板   
  38.     var userTree = new Ext.tree.TreePanel('users', {   
  39.         expanded:true  
  40.     });   
  41.     userTree.setRootNode(root);   
  42.     userTree.on('dblclick', this.onSelectUser);   
  43.     userTree.render();   
  44. }   
  45.   
  46. /**===============UI事件处理函数=======================*/  
  47. Controller.prototype.onSelectUser = function(node, event)   
  48. {   
  49.     alert(node.id);   
  50. }   
  51. var controller = new Controller();   
  52. Ext.onReady(controller.init, controller);   

        所有针对页面的处理函数都放在Controller对象中,各方法功能如下:

  • init方法在页面初始化时构建UI。
  • createUserTree方法调用DWR函数获取用户数据。
  • handlerUsers方法构建用户树组件。
  • onSelectUser方法在树结点双击时调用。

       上述代码在双击节点时会报错如下:

js 代码
  1. l.fireFn has no properties   
  2.    if (l.fireFn.apply(l.scope, arguments) === false) {  

       经过分析,错误是因为handlerUsers方法是做为DWREngine的方法执行的,因此在handlerUsers方法里调用this.onSelectUser给树节点添加事件时,找不到方法,因为此时的this是DWREngine的实例,而不是Controller实例。

       该死的DWR没有考虑回调函数的调用上下文问题!!!!

       有什么变通的解决办法可以达成我的目的呢?难道只能把这些都放在全局范围不成?

   发表时间:2007-07-05  
把this bind到你的function上去。

var self = this;
f1 = function(){self.f0();}
0 请登录后投票
   发表时间:2007-07-06  

我在调试的时候,也用过这个方法,到是可以解决问题,不过总感觉有点别扭,必须把一个实例传递到类的方法里,才能完成方法调用。

假定对这个实例的名称进行了重构,岂不是所有的方法都要改?

或者是另一个类需要调用此实例的方法,又如何处理呢?

0 请登录后投票
   发表时间:2007-07-06  
实际上你需要的是把一个function变成一个delegate。
0 请登录后投票
   发表时间:2007-07-06  
hax 写道
把this bind到你的function上去。

var self = this;
f1 = function(){self.f0();}


楼上说的应该是这个意思吧:

使用闭包特性可以解决,也就是不要用prototype的对象构造方法,而是把上述代码添加构造函数里,如:

function Controller()
{
    var self = this;
    
    handleUsers:function(users){
       self.onSelectUser();
    }
    onSelectUser:function(Node){
    }
}
0 请登录后投票
论坛首页 Web前端技术版

跳转论坛:
Global site tag (gtag.js) - Google Analytics