文章标题: 发 表 人: 版块:
 
主题:沙发级问题,关于Ext类设计技巧  发表时间: 2008-05-15 06:26
function class1(configObject)
{
  class1.superclass.constructor.call(this,{
           //config Object
  });
}

Ext.extend(class1,Ext.grid.GridPanel,
  {
       //overwrites
  }
);

我一般采用这样的方式继承Ext的一个组件,但是在overwrites这里,比如增加一个Store,在Store的config参数里的proxy里如果我要调用当前类的属性,用this关键字时,会得到一个错误的引用。(IE下提示很不友好,我猜想的),去查看API,结果发现好像在GridPanel里有一个scope参数,但是设置了以后,也没有用,反正对JS中的this很头痛啦,请问有没有什么好的设计方式,可以避免这种问题,顺便有没有好点的Eclipse的JS插件,我如果直接把Store写到构造方法中,这个问题就没有了。请问,overwrites重写机zhi
楼主: westsum
发表时间: 2008-05-15 06:26
        [引用回复]
Ext.extend(class1,Ext.grid.GridPanel,{});属于类的定义语句,你想想,类的定义肯定不能用this,this代表的是对象,更不能访问类中的属性了。另外要注意javascript对象的定义,比如下面的两种javascript对象写法都是错误的:
写法1:
var C={a:2,b:a*2};
alert(C.b);

写法2:
var C={a:2,b:this.a*2};
alert(C.b);
发言人:daxia VIP  楼层:1
发表时间: 2008-05-15 07:29
        [引用回复]
而回到你的问题:
Ext.extend(class1,Ext.grid.GridPanel,
 {
      //overwrites
 }
);

这一句里面,overwrites中定义的各种属性肯定就不能直接调用this或者前面定义的属性了。这个准确地说我觉得不应该是scope的问题,是javascript基础的问题。下面的语句是正确的:

function class1(configObject)
{
 class1.superclass.constructor.call(this,{
          //config Object
   this.store.laod();
 });
}

Ext.extend(class1,Ext.grid.GridPanel,
 {
   store:new Ext.data.JsonStore({});
      //overwrites
 }
);


而下面的语句写法却会出现语法错误:
function class1(configObject)
{
 class1.superclass.constructor.call(this,{
       
   this.a=new Ext.data.JsonStore({});
 });
}

Ext.extend(class1,Ext.grid.GridPanel,
 {
   store:this.a;
      //overwrites
 }
);

因为在我们使用这个类,因为store:this.a会在类定义的时候执行,这里this.a是不存在的。而this.a=new Ext.data.JsonStore({});则只有在我们创建一个class1实例,也就是调用new class1()这条语句的时候才会执行(才产生a这个属性)。

所以,楼主所说的问题,关键的是要掌握你所写的程序的执行流程,每一条语句执行时间。动态语言太灵活了,有时用得不好确实会带来不少麻烦,呵呵,以后用的过程中小心就是了。

至于你说的设计技巧,我觉得就把基础打好了,动态语言的技巧自然就会使出来,如果基础不好,那么技巧只会给自己带来更多的麻烦。总的来说,没有太多技巧。
发言人:daxia VIP  楼层:2
发表时间: 2008-05-15 07:39
        [引用回复]
您可能误会我的意思了。我把完整代码发一下。
function shopPanel(userObject)
{
   this.user = userObject;    
   this.user.start=0;
   this.user.limit=20;
   this.mycm = new Ext.grid.ColumnModel([{
          header: "名称",
          dataIndex: 'merName',
          width: 70,
          renderer:function(value,p,record)
          {
                  if(record.data["merState"].id==731)
                      return "<span style='color:red;'>"+value+"</span>";
                  return value;
          }
       },{
          header: "型号",
          dataIndex: 'merModelNo',
          width: 70
       },{
          header: "价格",
          dataIndex: 'merPrice',
          width: 50
       },{
          header: "数量",
          dataIndex: 'merAmount',
          width: 50
       },{
          header: "拍卖",
          dataIndex: 'ifRoupState',
          width:20,
          renderer:function(value, p, record){
               if(value)
                   return "<span style='color:red'>是</span>";
               return "否";
           }
       },{
          header: "热销",
          dataIndex: 'merState',
          width:20,
          renderer:function(value, p, record){
               if(value.id==731)
                   return "<span style='color:red'>是</span>";
               return "否";
           }
       },{
          header: "功能",
          width:60,
          renderer:function(value, p, record){    
               return "<a href='#'name='upMer'>更新<a> | <a href='#'>删除<a>";
           }
       }]);
   
   
   this.mygrid =new Ext.grid.GridPanel( {
       border:false,
       height:500,
       ds:this.mystroe,
       cm:this.mycm,
       loadMask: true,
       viewConfig: {
              forceFit:true,
           enableRowBody:true,
              showPreview:true,
           getRowClass : function(record, rowIndex, p, store){
                  if(this.showPreview){
                      p.body = '<div class="merItem"><div class="merItemIMG"><img src="'+record.data.merImagesAddress
                      +'"/></div><dl><dt>商品介绍:</dt><dd>'+
                      record.data.depict+'</dd></dl><div>';
                      return 'x-grid3-row-expanded';
               }
               return 'x-grid3-row-collapsed';
           }
       },
       bbar: new Ext.PagingToolbar({
             pageSize: 20,
              store:this.mystroe,
              displayInfo: true,
           displayMsg: '显示第 {0} 条到 {1} 条记录,一共 {2} 条',
           emptyMsg: "没有记录",
           items:[
               '-', {
               pressed: true,
               enableToggle:true,
               text: '描述(隐藏/显示)',
               cls: 'x-btn-text-icon details',
               toggleHandler:this.toggleDetails,
               scope:this
           }]
       })
   });
   shopPanel.superclass.constructor.call(this,
       {
           id:"shopControl",
           title:this.user.trueName+"的网店",
           iconCls:"shop_icon",
           border:false,
           closable:true,
           autoScroll:true,
           layout:"fit",
           items:[this.mygrid]
       }
   );
   this.addListener("beforedestroy",
       function(){
           this.user=null;
           if(window.userObject.shopMer)
           {
               window.userObject.shopMer=null;
           }
       },this);
   this.mycm.defaultSortable = true;
   this.mystroe.load({params:{id:this.user.id,start:0,limit:20}});
   this.mystroe.on("load",this.mygridRender,this);        
 
};
Ext.extend(shopPanel,Ext.Panel,
   {
       user:new Object(),
       toggleDetails: function (btn, pressed){
           var view = this.mygrid.getView();
           view.showPreview = pressed;
           view.refresh();
       },
       afterRender : function(){
               shopPanel.superclass.afterRender.call(this);              
       },
   mystroe:new Ext.data.Store
       ({    
                  proxy: new Ext.data.HttpProxy
                  ({
                      url: '/ctoc/test.do?id='+this.user.id//这里的this会有问题
                   }),
               // create reader that reads the Topic records
                   reader: new Ext.data.JsonReader
                   ({
                       root: 'mers',
                       totalProperty: 'totalCount',
                   fields: [
                           {name:'merName',mapping:"merName"},
                           {name:'merModelNo',mapping:"merModelNo"},                          
                           {name: 'merPrice', type: 'float',mapping:"merPrice"},
                           {name: 'merAmount', type: 'int',mapping:"merAmount"},
                           {name:'ifRoupState',mapping:"ifRoupState"},
                           {name:"depict",mapping:"depict"},
                           {name:"merSort",mapping:"staticDictionaryByMerSortNo"},
                           {name:"merState",mapping:"staticDictionaryByMerStateNo"},
                           {name:"merImagesAddress",mapping:"merImagesAddress"},
                           {name:"id",mapping:"id"},
                           {name:"shop",mapping:"shop"},
                           {name:"ifRecommendState",mapping:"ifRecommendState"}
                       ]
                   })
       });
       mygridRender:function(stroe,records,options)
       {
           var upMers = document.getElementsByName("upMer");
           for(var i = 0; i < upMers.length;i++)
           {
               upMers[i].onclick=this.upClickhandler.call(this);
           }
       },
       upClickhandler:function()
       {
           var othis = this;
           return function(e)
           {
               var record = othis.mygrid.getSelectionModel().getSelected();
               var tempWindow = new MerchandiseInfo(record);
               tempWindow.show(othis);
           }
       }
   }
);
当我把这个mystore放到构造方法中时,就可以用了
发言人: 61.178.41.** (匿名用户)  楼层:3
发表时间: 2008-05-15 09:06
        [引用回复]
尽然没有回复表单了?奇怪!
发言人:daxia VIP  楼层:4
发表时间: 2008-05-16 10:47
        [引用回复]
呵呵,我看你的代码,你都注明了的,在类定义语句中使用this.user.id肯定是有问题的。因为程序执行到这里的时候还没有对象实例,所以this使用起来是无效的,这时this指向的是window。

url: '/ctoc/test.do?id='+this.user.id//这里的this会有问题

你可以把url改成'/ctoc/test.do'
然后在调用store.load()方法的时候传递id参数即可,这是比较推荐的方式。只要能搞清楚问题的原因就可以了。
发言人:daxia VIP  楼层:5
发表时间: 2008-05-16 10:55
        [引用回复]
原来是这样~三Qdaxia,那么Ext.extend的第三个参数是不是类的prototype呢?其实我在store的load时加入了id参数了,我记得当时我这么做是因为在第一次请求的时候,参数里没有id我才加到url后面的。prototype里的this就是指向window,怪不得要给prototype里的方法设置scope了。
发言人:westsum  楼层:6
发表时间: 2008-05-17 08:31
        [引用回复]
还有,如果我在prototype里想要引用我这个类的一个成员时,不用this,那应该用什么方法呢?
发言人:westsum  楼层:7
发表时间: 2008-05-17 08:34
        [引用回复]
prototype是定义类的原型属性或方法,在定义的过程中肯定不能执行this。毕竟得到可能不是你需要的东西。但定义类的方法代码中,可以调用this。因为类的方法是直接通过“对象名.方法()”的形式来调用的。看下面的代码:

第一种是错误的用法:
Ext.extend(class1,Ext.grid.GridPanel,
{
  store:this.a;//这里会出错
}
);

下面的用法没问题:
Ext.extend(class1,Ext.grid.GridPanel,
{
  doSomething:function(){var a=this.a;};//方法的代码里面可以用this
}
);
因为var a=this.a这一句只有在调用doSomething方法的时候才会执行。此时肯定已经有了一个对象实例存在!
发言人:daxia VIP  楼层:8
发表时间: 2008-05-17 10:37
        [引用回复]
感觉这个讨论的非常深入我领会了许多.
发言人:woweiwokuang VIP  楼层:9
发表时间: 2008-06-04 05:25
        [引用回复]
.........我是没入门的人啊
云山雾罩
发言人:shan_gogo VIP  楼层:10
发表时间: 2008-06-04 09:36
其它版块:


标题:沙发级问题,关于Ext类设计技巧



论坛发言支持ubb格式(把HTML页面代码转化为UBB的工具) 添加/删除可视化编辑器
上传附件:
提示:您能上传的附件单个文件最大为2M
  
有新帖的版块
无新帖的版块

Copyright (C) 2008 vifir.com 开源人 渝ICP备06004507号 如有意见请与我们联系