• Extjs 自定义控件


    // JavaScript Document
    Ext.namespace('CRM.Panels');
    CRM.Panels.UserDetail = Ext.extend(Ext.Panel,{
         350,
      height:120,
      data:{
           ID: 0,
        FirstName: '',
        LastName: '',
        Email: '',
        City: '',
        Phone:''
      },
      split:true,
      tpl: new Ext.XTemplate([
        '<div>编号:{ID}</div>',
           '<div>姓名:{FirstName}-{LastName}</div>',
        '<div>电话:{Phone}</div>',
        '<div>城市:{City}</div>',
        '<div>邮箱:{Email}</div>'
      ]),
      initComponent:function(){
            CRM.Panels.UserDetail.superclass.initComponent.call(this);
        if(typeof this.tpl === 'string'){
            this.tpl = new Ext.XTemplate(this.tpl); 
        }
        this.addEvents('UAlert');//注册新事件
        this.addListener({//侦听函数 www.2cto.com
             UAlert: { //注册的新事件
           fn:this.onAlert,//调用onAlert方法
           scope: this
          }  
        });
      },
      //////////////
      onAlert: function(){
        alert('注册的新事件');
      },
      UAlert:function(){
        this.fireEvent('UAlert');
      },
      /////////////////////
      onRender: function(ct, position){
              CRM.Panels.UserDetail.superclass.onRender.call(this, ct, position);
        if(this.data){
            this.update(this.data);
        }
      },
      update: function(data){
       this.data = data;
       this.tpl.overwrite(this.body, this.data);
      // this.fireEvent('update',this.data);
      }
    });
    //把新建的自定义组件注册为一种xtype
    Ext.reg('UserDetail',CRM.Panels.UserDetail);
    /*使用:
    items:[
       {
        region:'west',
        xtype:'UserDetail',
        data: userData[0],
        title:'User Detail'
        }   
    ]*/
     
    在页面上:
    <script language="javascript">
     var userData = [
        {ID:1,FirstName:'Zhang',LastName:'Jinshan',Email:'zjs@qq.com',Phone:'123456',City:'ZhangPing'},
        {ID:2,FirstName:'Wang',LastName:'wu',Email:'wjf@qq.com',Phone:'123456',City:'ZhangPing'}
     ];
     Ext.onReady(function(){
      var userDetail = new CRM.Panels.UserDetail({
          applyTo:'body',
       title:'User Detail',
       data:userData[0]
      });
        updateContact = function(event, el, data){
             userDetail.update(data.data);//调用更新数据
      }
      Ext.get('xt').on('click',updateContact,this,{data:userData[1]});
      Ext.get('alert').on('click',function(){
                userDetail.UAlert();
                });
     })
    </script>
    <button id="xt">点击</button>
    <button id="alert">注册的新事件</button>
     
     
     
    
    //////////////////////////////////
    
    ExtJS中的面向对象设计,组件化编程思想/**
    * @author: Lilf
    * Description: ExtJS中的面向对象设计,组件化变成思想
    */
    /****************************扩展VTypes类,增加年龄的验证****************************/
    Ext.apply(Ext.form.VTypes, {
         "age": function(_v){
             if (/^d+$/.test(_v)) {
                 var intExp = parseInt(_v);
                 if (intExp < 200) 
                     return true;
             }
             return false;
         },
         ageText: "请输入正确的年龄格式,如:23"
    });
    /****************************继承自FormPanel的表单组件,用来构件Window***************************/
    PersonInfoFormPanel = Ext.extend(Ext.form.FormPanel, {
         constructor: function(){
             PersonInfoFormPanel.superclass.constructor.apply(this, [{
                 baseCls: "x-plain",
                 buttonAlign: "right",
                 labelWidth: 30,
                 defaultType: "textfield",
                 defaults: {
                     anchor: "95%",
                     labelStyle: "text-align:right"
                 },
                 items: [{
                     fieldLabel: "姓名",
                     name: "name"
                 }, {
                     fieldLabel: "年龄",
                     name: "age",
                     vtype: "age"//验证年龄(通过vtype类型来验证)
                 }, {
                     xtype: "combo",
                     mode: "local",//本地数据
                     readOnly: true,
                     fieldLabel: "性别",
                     displayField: "sex",//显示下拉框的内容
                     triggerAction: "all",//在选择时,显示所有的项
                     value: "男",//默认值
                     store: new Ext.data.SimpleStore({
                         fields: ["sex"],
                         data: [["男"], ["女"]]
                     }),
                     name: "sex"//绑定字段
                 }]
             }])
         },
         //---以下为PersonInfoFormPanel类对外提供的方法---
         getValues: function(){
             if (this.getForm().isValid()) 
                 return new Ext.data.Record(this.getForm().getValues());
             else 
                 throw new Error("验证没有通过");//自定义异常
         },
         setValues: function(_r){
             this.getForm().loadRecord(_r);
         },
         reset: function(){
             this.getForm().reset();
         }
    });
    /**************继承自Window的基类,insertWindow与updateWindow都由此继承****************/
    baseWindow = Ext.extend(Ext.Window, {
         form: null,
         constructor: function(){
             this.form = new PersonInfoFormPanel();//实例化PersonInfoFormPanel类
             baseWindow.superclass.constructor.apply(this, [{
                 plain: true,
                  350,
                 //title: "新增人员",
                 modal: true,
                 resizable: false,
                 closeAction: "hide",
                 defaults: {
                     style: "padding:5px"
                 },
                 items: this.form,
                 buttons: [{
                     text: "确 定",
                     handler: this.onSubmitClick,//提交事件调用
                     scope: this
                 }, {
                     text: "取 消",
                     handler: this.onCancelClick,//取消事件调用
                     scope: this
                 
                 }]
             }]);
             //给insertWindow对象添加事件(事件冒泡)
             this.addEvents("submit");
         },
         //提交事件处理函数
         onSubmitClick: function(){
             try {
                 //发布事件
                 this.fireEvent("submit", this, this.form.getValues());//调用PersonInfoFormPanel类中自定义的方法getValues
                this.close();
                
            } 
            catch (_err) {
                Ext.Msg.alert("系统提示", _err.description);//扑捉自定义错误或异常
            }
        },
        //取消事件处理函数
        onCancelClick: function(){
            this.close();
        },
        //重置与隐藏事件处理函数
        close: function(){
            this.form.reset();
            this.hide();
        }
        
    });
    /*******************insertWindow类****************************/
    insertWindow = Ext.extend(baseWindow, {
        title: "新增人员"
    });
    /*****************updateWindow类******************************/
    updateWindow = Ext.extend(baseWindow, {
        title: "修改人员",
        load: function(_r){
            this.form.setValues(_r);
        }
    });
    /********根据上面组件创建新的GridPanel类,它就像我们根据不同的零件设计出来的汽车************
    * ExtJs自定义PersonListGridPanel类
    * 该类继承自GridPanel[使用Ext.extend(superClass,override Object)方法实现继承],
    * 并override了该类的构造函?hu数
    * 构造函数内部继承自GridPanel的构造函数[apply(this,arguments)实现继承]
    * 该类实现了如何对外部公布一个事件
    * 在构造函数中添加一个事件[this.addEvents("事件名称")]
    * 然后使用this.fireEvent("事件名称",参数)来发布此事?件
    * 最后在客户端调用的时候来订阅该事?jian件
    */
    PersonListGridPanel = Ext.extend(Ext.grid.GridPanel, {
        _window: null,
        _updateWin: null,
        constructor: function(_url){
            this._window = new insertWindow();//insertWindow对象引用
            this._updateWin = new updateWindow();//updateWindow对象引用
            PersonListGridPanel.superclass.constructor.apply(this, [{
                renderTo: Ext.getBody(),
                 550,
                height: 200,
                frame: true,
                layout: "form",
                //工具栏
                tbar: [{
                    text: "add",
                    handler: function(){
                        this._window.show();
                    },
                    scope: this
                }, "-", {
                    text: "update",
                    handler: function(){
                        this._updateWin.show();
                        try {
                            this._updateWin.load(this.getSelected());
                        } 
                        
                        
                        catch (_err) {
                            Ext.Msg.alert("系统提示", _err.description);
                            this._updateWin.close();
                        }
                    },
                    scope: this
                }, "-", {
                    text: "delete",
                    handler: this.onRemovePerson,
                    scope: this
                }],
                enableColumnMove: false,
                //列模板
                columns: [{
                    header: "Name",
                    menuDisabled: true,
                    dataIndex: "name"
                }, {
                    header: "Age",
                    menuDisabled: true,
                    dataIndex: "age"
                }, {
                    header: "Sex",
                    menuDisabled: true,
                    dataIndex: "sex"
                }],
                //数据源
                store: new Ext.data.JsonStore({
                    autoLoad: true,
                    url: _url,
                    fields: ["name", "age", "sex"]
                }),
                //选中模板
                selModel: new Ext.grid.RowSelectionModel({
                    singleSelect: true,
                    listeners: {
                        "rowselect": {
                            fn: this.onRowSelected,
                            scope: this
                        }
                    }
                })
            
            }]);
            //添加事件
            this.addEvents("rowselect");
            //事件订阅
            this._window.on("submit", this.onInsertWinSubmit, this);
            this._updateWin.on("submit", this.onUpdateWinSubmit, this);
        },
        //----- 以下为自定义方法---------
        //获得选中的记录
        getSelected: function(){
            var _sm = this.getSelectionModel();
            if (_sm.getCount() == 0) 
                throw new Error("你没有选中任何记录,请选择一条记录后重试");
            return _sm.getSelected();
        },
        //插入一条记录
        insert: function(_r){
            this.getStore().add(_r);
        },
        //更新选中的记录
        update: function(_r){
            try {
                var _rs = this.getSelected();
                var _data = _rs.data;
                for (var _i in _data) {
                    _rs.set(_i, _r.get(_i));
                };
                _rs.commit();
            } 
            catch (_err) {
            
            }
            
        },
        //删除选中的记录
        remove: function(){
            try {
                var _rs = this.getSelected();
                Ext.Msg.confirm("系统提示", "你确定删除吗?", function(_btn){
                    if (_btn == "yes") 
                        this.getStore().remove(_rs);
                }, this);
            } 
            catch (_err) {
                Ext.Msg.alert("系统提示", _err.description);
            }
        },
        //-------以下为自定义事件处理函数------------
        //添加事件
        onInsertWinSubmit: function(_win, _r){
            this.insert(_r);
        },
        //修改事件
        onUpdateWinSubmit: function(_win, _r){
            this.update(_r);
        },
        //删除事件
        onRemovePerson: function(){
            this.remove();
        },
        //选中事件
        onRowSelected: function(_sel, _index, _r){
            this.fireEvent("rowselect", _r);//发布事件
        }
    })
    //////////////
    如何编写ExtJS自定义控件
    // 1、引入命名空间
    Ext.namespace("ExtUD.Ext");//相当于java中包的作用
    // 2、编写自定义控件类
    ExtUD.Ext.UDPanel = Ext.extend(Ext.Panel, {
       title : '自定义控件',
       html:'自定义控件面板',
       layout:'fit',
       getAlert:function(){alert('自定义控件函数!');}
      });
    // 3、注册控件
    Ext.reg('udpanel', ExtUD.Ext.UDPanel);//第一个参数为自定义控件的xtype
    
    //4、使用自定义控件
    Ext.onReady(function() {
    var temp = new ExtUD.Ext.UDPanel({
       renderTo : document.body
      });
     temp.show(); 
     temp.getAlert();
    });
     
    如何编写ExtJS自定义控件
    // 1、引入命名空间
    Ext.namespace("ExtUD.Ext");//相当于java中包的作用
    // 2、编写自定义控件类
    ExtUD.Ext.UDPanel = Ext.extend(Ext.Panel, {
       title : '自定义控件',
       html:'自定义控件面板',
       layout:'fit',
       getAlert:function(){alert('自定义控件函数!');}
      });
    // 3、注册控件
    Ext.reg('udpanel', ExtUD.Ext.UDPanel);//第一个参数为自定义控件的xtype
    
    //4、使用自定义控件
    Ext.onReady(function() {
    var temp = new ExtUD.Ext.UDPanel({
       renderTo : document.body
      });
     temp.show(); 
     temp.getAlert();
    });
    //单文本加单铵钮控件
    Ext.Diy.GridCodeName1 = Ext.extend(Ext.Panel, {
     winWidth:500,//定义弹出窗体的大小
     id:'',//窗体ID
     fieldLabel:'',
     labelWidth:60,
     allowBlank:false,//验证是否可为空
     blankText:'This field is required',//空白文本
     displayField:'NAME',//值1
     valueField:'VALUE',//值2
     codeField:'CODE',//值3
     oldValue:'',//缓存旧值
     autoDoLoad:true,//自动加载
     pageSize:10,//页显示行数
     remoteSort:true,//是否可排序
     showLabel: false,//是否显示label
        initComponent:function() {//在这里定义控件样式与弹出窗体样式等,并获得值
      //暂存调用页面传下来的参数
         var id=this.id;
         var tmpNameField=this.displayField;
         var tmpValueField=this.valueField;
         var tmpCodeField=this.codeField;
         var winWidth = this.winWidth;
         var pageSize = this.pageSize;
         var remoteSort = this.remoteSort;
         var tabIndex = -1;//分页
         var cm;//列头
         if(this.tabIndex!==undefined){
          tabIndex = this.tabIndex;
         }
         if(this.cm!==undefined){
          cm = this.cm;
         }else{
          cm = new Ext.grid.ColumnModel([
        new Ext.grid.CheckboxSelectionModel({singleSelect:true}),
        {id:tmpValueField,header: "值",  0, sortable: false, dataIndex: tmpValueField, hidden:true},
        {header: "编码",  70, sortable: true, dataIndex: tmpCodeField},
        {header: "名称",  100, sortable: true, dataIndex: tmpNameField}
             ]);
         }
         
         var readerPanel;//定义要读取的列标题
         if(this.readerPanel!==undefined){
          readerPanel = this.readerPanel;
         }else{
          readerPanel = new Ext.data.Record.create([
        {name: tmpNameField},
        {name: tmpValueField},
        {name: tmpCodeField}
          ]);
         }
      //读取数据
      var reader = new Ext.data.XmlReader({
                   record: 'ROW',
                   totalRecords: "TOTALCOUNT"
             },
             readerPanel//把数据保存到溶器中
            );
         //定义存数据的溶器
      var tmpStore = new Ext.data.Store({
       url: 'servlet/ajaxservlet',
             reader: reader,
             remoteSort:remoteSort,
             listeners:{
              load:function(store,records){
               Ext.getCmp(id).fireEvent('afterLoad',store,records);
              }
             }
      });
      
      var valueStore = new Ext.data.Store({
       url: 'servlet/ajaxservlet',
             reader: reader,
             remoteSort:remoteSort,
             listeners:{
              load:function(store,records){
         Ext.getCmp(id).setValueByRecord(records[0]);
        }
             }
      });
      //判断排序
      if(this.sortInfo!==undefined){
       tmpStore.setDefaultSort(this.sortInfo.field,this.sortInfo.direction);
      }
      this.valueStore = valueStore;
      this.store = tmpStore;
      if(this.autoDoLoad){
       this.doLoad();//加载数据
      }
      
           //数据获取情况提示信息
      var pagingBar = new Ext.PagingToolbar({
       displayInfo:true,
       emptyMsg:"没有数据显示",
       displayMsg:"显示从第{0}条数据到第{1}条数据,共{2}条数据",
       store:tmpStore,
       pageSize:pageSize
         });
      //数据加载提示
      var grid = new Ext.grid.GridPanel({
       store: tmpStore,
       loadMask:{msg:'数据加载中...'},
       cm: cm,
       sm: new Ext.grid.CheckboxSelectionModel({singleSelect:true}),
             viewConfig: {
                 forceFit:true
             },
             tbar:[{//以下设置查询
        xtype:'tbtext',
        text:'查询关键字:'
       },{
        xtype:'textfield',
        id:id+'searchItemKey'
       },'   ',{
        xtype:'tbbutton',
        text:'查询',
        handler:function(){
         var tmpSearchKey = Ext.getCmp(id+'searchItemKey').getValue();
         Ext.getCmp(id).doSearch(tmpStore,tmpSearchKey,'','');
        },
        pressed:true
       }],
             bbar:pagingBar,
           
       buttons: [{
        text:'确定',
        menuAlign:'center',
        handler : function(){   
         var record = grid.getSelectionModel().getSelected();// 返回值为 Record 类型
         if(record==null){
          //Ext.MessageBox.alert('提示', '请选择一条数据!');
          Ext.getCmp(id).clearValue();
          Ext.getCmp(id).fireEvent('onChange',null,'','');
          win.hide();
          return;
         }else{
          Ext.getCmp(id).setValueByRecord(record);//以value值为索引填充数据到控件文本框
          win.hide();
         }
        }
       },{
        text:'取消',
        menuAlign:'center',
        handler : function(){   
         win.hide();
        }
       }        
             ],
         
       autoWidth: true,
             iconCls:'icon-grid'
      });
       //双击数据行填充数据到控件文本框
      grid.on("rowdblclick",function(thisGrid,rowIndex,e){
       var record = thisGrid.getStore().getAt(rowIndex);
       Ext.getCmp(id).setValueByRecord(record);
       win.hide(); 
         });
      //定义窗体详细信息
      var win = new Ext.Window({
             title: '请选择',
              winWidth,
             defaults:{autoHeight: true},
             modal: true,
             closeAction: 'hide',
             bodyStyle: 'padding:10px;',
             items:grid
         });
         //定义窗体显示内容样式
         Ext.apply(this,{
          border:false,
          bodyBorder:false,
          items:[{
        layout:'column',
        border: false,
        items:[{
         columnWidth:0.9,
         labelWidth:this.labelWidth,
         layout: 'form',
         border: false,
         items:[{
          xtype:'textfield',
          fieldLabel: this.fieldLabel,
          anchor:'100%',
          id:id+'_code',
          readOnly:true,
          tabIndex:tabIndex,
          listeners:{
           specialkey : function(field, e){
            if (e.getKey() == Ext.EventObject.ENTER) {
             Ext.getCmp(id).setValueByCode(field.getValue());
            }
           }
          }
         }]
        },{
         columnWidth:0.1,
         border: false,
         items:[{
          xtype:'button',
          id:id+'_btn',
          text:'  ',
          handler:function(){
           if(Ext.getCmp(id).fireEvent("beforeClick")===false){
            return;
           }
           win.show();
           win.center();
           Ext.getCmp(id).fireEvent("afterClick");
          },
          pressed:true
         }]
        }]
       },{
        xtype:'textfield',
        id:id+'_value',
        hidden:true
       }]
         });
         //注册控件事件
         Ext.Diy.GridCodeName1.superclass.initComponent.apply(this, arguments);
         this.addEvents({'onChange':true},{'codeInvalid':true},{'beforeClick':true},{'afterClick':true},{'afterLoad':true}); 
        },
        //以下定义控件事件
        setLabelDisplay: function(p_showLabel){
      this.showLabel=p_showLabel;
      if(p_showLabel){
       document.getElementByIdx_x(this.id).childNodes[0].style.display="none";
       var tmpDiv=document.getElementByIdx_x("mylbl_"+this.id);
       if(tmpDiv){
        document.getElementByIdx_x("mylbl_"+this.id+"_td").innerHTML=document.getElementByIdx_x(this.id+"_name").value;
        tmpDiv.style.display="block";
       }else{
        tmpDiv = document.createElement_x("div");
        tmpDiv.id="mylbl_"+this.id;
        tmpDiv.innerHTML="<div style='100%;height:25px;' class='diyform-label-div'>"+
          "<table width='100%' border='0' cellspacing='0' cellpadding='0'><tr ><td width='"+this.labelWidth+"'>"+this.fieldLabel+
                ":</td><td id='mylbl_"+this.id+"_td' class='diyform-label-td'>"+
                document.getElementByIdx_x(this.id+"_name").value+"</td></tr></table></div>";
        tmpDiv.style.width=document.getElementByIdx_x(this.id).style.width;
        document.getElementByIdx_x(this.id).appendChild(tmpDiv);
       }
      }else{
       document.getElementByIdx_x(this.id).childNodes[0].style.display="block";
       try{document.getElementByIdx_x(this.id).removeChild(document.getElementByIdx_x("mylbl_"+this.id));}catch(ex){}
      }
     },
        doLoad:function(addCon){
      if(addCon!==undefined){
       this.clearValue();
       this.condition=addCon;
      }
      this.doSearch(this.store,'','','');
     },
     doSearch:function(store,searchKey,value,code){
      var tmpParam=[];
      tmpParam.push(searchKey);
      tmpParam.push(value);
      tmpParam.push(code);
      if(this.condition!==undefined){
       tmpParam.push(this.condition);
      }
      var parmObj=createRequestXml(this.classUrl,"GetData",this.method,tmpParam.join(','));
         store.baseParams={
             requestType: 'requestData4DiyGrid',
             requestCharSet:'UTF8',
             requestLisence: '1',
             requestXml: parmObj
            };
            var pageSize = this.pageSize;
            store.load({params:{start:0, limit:pageSize}});
     },
        unedit:function(flag){
         Ext.getCmp(this.id+"_btn").setDisabled(flag);
         Ext.getCmp(this.id+"_code").setDisabled(flag);
        },
        clearValue:function(){
         this.oldValue=Ext.getCmp(this.id+'_value').getValue();
         Ext.getCmp(this.id+"_value").setValue('');
         Ext.getCmp(this.id+"_code").setValue('');
        },
        changeValue:function(record,value,oldValue){
         if(value!=oldValue){
          this.fireEvent('onChange',record,value,oldValue);
         }
        },
        codeInvalid:function(){
      this.fireEvent('codeInvalid');     
        },
        setValue:function(value){
         if(value==null||value==""){
          return;
         }
         var record;
         var i=0,j=this.store.getCount();
         for(;i<j;i++){
          record = this.store.getAt(i);
          if(record.get(this.valueField)==value){
           this.setValueByRecord(record);
           break;
          } 
         }
         if(i==j){
          this.doSearch(this.valueStore,'',value,'');
         }
        },
        setDtlValue:function(dtl,ifFireEvent){     
         this.oldValue=Ext.getCmp(this.id+'_value').getValue();
         Ext.getCmp(this.id+"_value").setValue(dtl.value);
         Ext.getCmp(this.id+"_code").setValue(dtl.code);
         if(ifFireEvent==false){
         
         }else{
          this.changeValue(null,dtl.value,this.oldValue);
         }
         
        },
        setValueByCode:function(code){
         var record;
         var i=0,j=this.store.getCount();
         for(;i<j;i++){
          record = this.store.getAt(i);
          if(record.get(this.codeField)==code){
           this.setValueByRecord(record);
           break;
          } 
         }
         if(i==j){
          this.doSearch(this.valueStore,'','',code);
         }
        },
        setValueByRecord:function(record){
         if(record!=null){
          this.clearValue();
       Ext.getCmp(this.id+'_value').setValue(record.get(this.valueField));
       Ext.getCmp(this.id+'_code').setValue(record.get(this.codeField));
       this.changeValue(record,record.get(this.valueField),this.oldValue);
      }else{
       if(Ext.getCmp(this.id+'_code').getValue()!=""){
        Ext.MessageBox.alert('提示','找不到该信息');
        Ext.getCmp(this.id+'_code').focus();
       }
       this.clearValue();
       this.fireEvent('codeInvalid');
      }
        },
     getValue:function(){return Ext.getCmp(this.id+"_value").getValue();}
     });
    // 4、注册控件
    Ext.reg('diygridcodename1', Ext.Diy.GridCodeName1);//第一个参数为自定义控件的xtype
     
     
    调用方式:
          id:'LM_SPEC',
          xtype : 'diygridcodename1',//自定义控件 diygridcodename
          fieldLabel:'规格',
          labelWidth:80,
          allowBlank:false,
          classUrl:classUrl,
          method:'getSpecInfo',
          readerPanel:[{name: 'CODE'},{name: 'VALUE'},{name: 'NAME'}],
          cm:new Ext.grid.ColumnModel([
           new Ext.grid.CheckboxSelectionModel(),
              {header: "编号", 100, sortable: true,dataIndex: 'NAME'},
              {header: "规格", 120,unedit:false, sortable: true,dataIndex: 'CODE'}
          ]),
          listeners:{
              onChange:function(p_record,p_value,p_oldValue){
               //ifdef = p_record.get("SOM_IFDEFAULT");
              },
           beforeClick:function(){
               if(!checkbaseunit()){
                Ext.MessageBox.alert("提示","主要单位不能为空!");
                return;
               }
           }
          },
          anchor : '98%'//占用总宽度的百份比
    

      

  • 相关阅读:
    rpm -ivh 这个ivh是干什么的
    记录各种资源链接的吧
    Bootstrap中表单控件状态(验证状态)
    jquery input 实时监听输入
    socket.error: [Errno 98] Address already in use
    bad interpreter: Text file busy
    Linux下安装pip(遇到了python2.6升级为python2.7道路上的坑,原因已经找到,只差临门一脚了,以后补上)
    完全卸载mysql数据库教程
    数字签名证书的事儿(转)
    设计模式-外观模式
  • 原文地址:https://www.cnblogs.com/anbylau2130/p/3637635.html
Copyright © 2020-2023  润新知