概述


大型的应用在开发和运维上都存在着困难。应用功能的调整和开发人员的调动都会影响对项目的掌控。ExtJS4带来了一种新的应用结构。这种结构不止用于组织代码,也能有效的减少必要的代码量。

这次ExtJS4的应用结构采用了MVC的形式。在这种形式下,Models和Controllers第一次被引入了ExtJS。目前已经有了许多MVC式的结构,这些结构大部分是大同小异。这里是我们定义的MVC结构:

  • Model(模型)是字段及数据的集合(比如一个用户模型包含用户名字段和密码字段)。模型用于数据的展示,也可以通过关联关系关联到其他的Model上。模型的工作形式很像ExtJS3的Record类,并通常和Stores一起使用将数据展示到grids和其他组件中;
  • View(视图)是组件的的一种类型。grids、trees和panels都是视图;
  • Controller(控制器)用于将代码组合起来使应用运行。

在这篇文章中我们将建立一个简单的用户数据管理应用。通过这个应用可以对ExtJS4的MVC结构有初步的了解。

ExtJS4的MVC结构提供了一套结构性和一致性的规范。在开发中会发现,Ext的MVC应用是由自定义类和框架代码构成的。按惯例,先说下采用MVC结构开发的好处:

  • 所有的应用采用相同的模式工作,只需要一次学习;
  • 所有的应用采用相同的模式工作,便于代码共享;
  • 可以基于ExtJS提供的开发工具进行开发优化。

文件结构


使用ExtJS的MVC模式开发应用需要使用统一的文件结构 。应用所有的类都放在app目录下。按MVC结构,在app目录下需要建立model、view、store和controller等子目录。下图为我们的一个示例应用开发完成后的目录结构:

在这个例子中我们封装了一个应用程序称为“account_manager”,ExtJS4的sdk环境置于ext-4.0目录中。如下为index.html的代码:

   1:  <html>
   2:  <head>
   3:      <title>Account Manager</title>
   4:      <link rel="stylesheet" type="text/css" href="ext-4.0/resources/css/ext-all.css">
   5:      <script type="text/javascript" src="ext-4.0/ext-debug.js"></script>
   6:      <script type="text/javascript" src="app.js"></script>
   7:  </head>
   8:  <body></body>
   9:  </html>

从app.js开始创建应用


每个ExtJS4的MVC应用都是通过一个Appliaction类的实例启动。在Application中包含应用的全局定义(比如应用名称),以及应用中所使用到的模型、视图和控制器的引用。此外,Application类还有一个launch函数。launch函数在页面加载完成后执行。

接下来我们将创建一个account_manager应用来管理用户账户信息。首先需要为这个应用定义一个全局的命名空间。所有ExtJS4的MVC应用应该只有一个全局命名空间,应用中所有的类都置于这个命名空间下。一般我们会给这个命名空间定义一个较短的名称,这里我们使用“AM”。

   1:  Ext.application({
   2:      name: 'AM',
   3:   
   4:      appFolder: 'app',
   5:   
   6:      launch: function() {
   7:          Ext.create('Ext.container.Viewport', {
   8:              layout: 'fit',
   9:              items: [
  10:                  {
  11:                      xtype: 'panel',
  12:                      title: 'Users',
  13:                      html : 'List of users will go here'
  14:                  }
  15:              ]
  16:          });
  17:      }
  18:  });

这里实现的功能很简单。首先,我们调用 Ext.application创建了一个Application类的实例,并将之命名为“AM”。同时,这里自动创建了一个全局变量“AM”,并为Ext.Loader注册了一个命名空间。然后我们设置appFolder属性为app目录。最后我们设置了launch函数,并在函数中创建了包含一个panel的Viewport来填充整个屏幕。

定义一个控制器(controller)


可以说控制器(controller)是把整个应用绑定在一起的胶水。它们(控制器)执行的工作是事件监听(通常来自view)并做出相应处理。

我们继续完成account_manager应用,接下来我们将创建一个控制器。新建一个js文件app/controller/Users.js,代码如下:

   1:  Ext.define('AM.controller.Users', {
   2:      extend: 'Ext.app.Controller',
   3:   
   4:      init: function() {
   5:          console.log('Initialized Users! This happens before the Application launch function is called');
   6:      }
   7:  });

将我们新建的控制器Users添加到应用中,为app.js添加属性如下:

   1:  Ext.application({
   2:      ...
   3:   
   4:      controllers: [
   5:          'Users'
   6:      ],
   7:   
   8:      ...
   9:  });

当我们通过index.html在浏览器中加载应用时,控制器Users也会被自动加载(因为我们在上面的应用定义中做了设置),然后Users的init函数会被调用——在Application类的launch函数执行之前。

在控制器与视图(view)的交互中,init函数的作用十分重要,通常它会和控制器的另一个函数control一起使用。使用control函数比较容易实现对视图事件的监听和响应。

我们调整下Users控制器,通过control函数来看看panel什么时候被render(渲染):

   1:  Ext.define('AM.controller.Users', {
   2:      extend: 'Ext.app.Controller',
   3:   
   4:      init: function() {
   5:          this.control({
   6:              'viewport > panel': {
   7:                  render: this.onPanelRendered
   8:              }
   9:          });
  10:      },
  11:   
  12:      onPanelRendered: function() {
  13:          console.log('The panel was rendered');
  14:      }
  15:  });

在上面的代码中,我们调整了users控制器的init函数,使用this.control为应用中的视图建立了监听。control函数使用新的ComponentQuery引擎简单快速的实现了对页面上的组件的引用。(关于ComponentQuery的内容请参看文档。简单地说,就是使用css式的选择器实现了对页面上组件的快速匹配)。

在上面的init函数中我们使用了“viewport > panel”这样的语句。“viewport > panel”是一个选择器,它的含义是“找到Viewport的每个直接子Panel”。随后我们提供了一个对象,在这个对象中包含事件名称(上例中即是render)及相应的处理函数。实现的效果是任何一个匹配我们定义的选择器的组件触发了render事件后即会调用onPanelRendered函数。

现在运行下应用看看效果:

并不是一个很炫的应用,但它已经展示了使用MVC管理代码的好处。接下来我们给这个应用添加一个表格,使它变得丰满些。

定义一个视图


目前为止我们的应用只有两个文件、极少的几行代码。现在我们想给这个应用添加一个表格来展示系统中的用户。是时候使用视图了。

视图只是一个组件,是继承自ExtJS现有组件的类。我们将定义一个用户信息列表类,新建文件app/view/user/List.js,代码如下:

   1:  Ext.define('AM.view.user.List' ,{
   2:      extend: 'Ext.grid.Panel',
   3:      alias : 'widget.userlist',
   4:   
   5:      title : 'All Users',
   6:   
   7:      initComponent: function() {
   8:          this.store = {
   9:              fields: ['name', 'email'],
  10:              data  : [
  11:                  {name: 'Ed',    email: 'ed@sencha.com'},
  12:                  {name: 'Tommy', email: 'tommy@sencha.com'}
  13:              ]
  14:          };
  15:   
  16:          this.columns = [
  17:              {header: 'Name',  dataIndex: 'name',  flex: 1},
  18:              {header: 'Email', dataIndex: 'email', flex: 1}
  19:          ];
  20:   
  21:          this.callParent(arguments);
  22:      }
  23:  });

如上,这个视图类也只是一个简单的普通类。我们只是继承了Grid组件,定义了一个别名,通过这个别名我们可以使用xtype调用这个类(一般是这么用,还有别的用处)。同时我们还添加了列表需要使用的store和columns信息。

接下来我们需要将这个视图添加到Users控制器中。我们已经使用'widget.'形式设置了类的别名,所以可以直接使用“userlist”作xtype,就跟以前使用“xtype: ‘panel’”一样。

   1:  Ext.define('AM.controller.Users', {
   2:      extend: 'Ext.app.Controller',
   3:   
   4:      views: [
   5:          'user.List'
   6:      ],
   7:   
   8:      init: ...
   9:   
  10:      onPanelRendered: ...
  11:  });

然后我们在应用的Viewport布局中调用这个类。这需要在app.js中修改launch函数:

   1:  Ext.application({
   2:      ...
   3:   
   4:      launch: function() {
   5:          Ext.create('Ext.container.Viewport', {
   6:              layout: 'fit',
   7:              items: {
   8:                  xtype: 'userlist'
   9:              }
  10:          });
  11:      }
  12:  });

这里还有一点需要注意,在控制器的views数组中,我们设置了'user.List' 。这告诉了应用去调用视图文件view/user/List.js,这样在应用加载时就可以直接使用这个文件了。这里使用了ExtJS4新增的的动态调用服务以从服务器中获取文件。现在再看看我们的acount_manager应用:

控制表格


请注意,代码更新后onPanelRendered函数仍然被调用了。这表名我们自定义的列表类仍然匹配“viewport > panel”选择器。因为我们自定义的userlist类继承自Grid类,Grid类继承自Panel类。

此时我们添加到选择器中的监听仍然被Viewport直属的Panel类或其子类所调用,我们可以利用这点对我们的用户信息列表的功能做些强化。还是使用init函数,不过要改为监听用户信息记录上的双击事件,使双击后可以对用户信息进行编辑。调整控制器:

   1:  views: [
   2:          'user.List'
   3:      ],
   4:   
   5:      init: function() {
   6:          this.control({
   7:              'userlist': {
   8:                  itemdblclick: this.editUser
   9:              }
  10:          });
  11:      },
  12:   
  13:      editUser: function(grid, record) {
  14:          console.log('Double clicked on ' + record.get('name'));
  15:      }

对控制器Users我们做了如下调整:

修改了ComponentQuery的选择器,现在只是使用‘userlist’;修改监听的事件为“itemdblclick”;调整事件处理函数为“editUser”。再次运行应用,双击记录时会在控制台上输出相应的信息:

应用运行的很好。但是我们不会满足于简单的在控制台上输出信息,我们希望能真正的编辑用户信息。这里要创建一个新的视图:app/view/user/Edit.js:

   1:  Ext.define('AM.view.user.Edit', {
   2:      extend: 'Ext.window.Window',
   3:      alias : 'widget.useredit',
   4:   
   5:      title : 'Edit User',
   6:      layout: 'fit',
   7:      autoShow: true,
   8:   
   9:      initComponent: function() {
  10:          this.items = [
  11:              {
  12:                  xtype: 'form',
  13:                  items: [
  14:                      {
  15:                          xtype: 'textfield',
  16:                          name : 'name',
  17:                          fieldLabel: 'Name'
  18:                      },
  19:                      {
  20:                          xtype: 'textfield',
  21:                          name : 'email',
  22:                          fieldLabel: 'Email'
  23:                      }
  24:                  ]
  25:              }
  26:          ];
  27:   
  28:          this.buttons = [
  29:              {
  30:                  text: 'Save',
  31:                  action: 'save'
  32:              },
  33:              {
  34:                  text: 'Cancel',
  35:                  scope: this,
  36:                  handler: this.close
  37:              }
  38:          ];
  39:   
  40:          this.callParent(arguments);
  41:      }
  42:  });

我们再次定义了一个ExtJS组件的子类。这次是继承了Ext.window.Window。我们仍需要使用initComponent函数为编辑视图Edit添加表单元素和按钮。布局采用了“fit”形式,窗体下只有一个form面板,在form面板中有两个文本框用以编辑姓名和邮件地址。最后还定义了两个按钮用以关闭窗体和保存更改。

然后我们要做的就是把这个编辑视图添加到控制器,并将用户信息添加到编辑视图。见代码:

   1:  Ext.define('AM.controller.Users', {
   2:      extend: 'Ext.app.Controller',
   3:   
   4:      views: [
   5:          'user.List',
   6:          'user.Edit'
   7:      ],
   8:   
   9:      init: ...
  10:   
  11:      editUser: function(grid, record) {
  12:          var view = Ext.widget('useredit');
  13:   
  14:          view.down('form').loadRecord(record);
  15:      }
  16:  });

重点看一下editUser函数。在这个函数中,我们使用了函数’Ext.widget’,其功能类似于Ext.create('widget.useredit')。然后我们再次使用ComponentQuery建立了到编辑视图的映射。每个ExtJS4的组件都有一个down函数以接收ComponentQuery的选择器并快速的查找选择器对应的直属子元素。

双击列表中的行,效果如下图:

创建model和store


现在我们已经做好了编辑视图,也差不多可以进行编辑和保存了。但是在做这些工作之前,我们还需要对我们的代码进行一次重构。

现在的AM.view.user.List组件中,store是写在List类中。虽然现在应用也运行的很好,但是我们更倾向于将store独立出来,这样也便于我们对store中的数据进行处理。现在我们开始将store中从List视图中拆分出来放到app/store/Users.js中:

   1:  Ext.define('AM.store.Users', {
   2:      extend: 'Ext.data.Store',
   3:      fields: ['name', 'email'],
   4:      data: [
   5:          {name: 'Ed',    email: 'ed@sencha.com'},
   6:          {name: 'Tommy', email: 'tommy@sencha.com'}
   7:      ]
   8:  });

然后我们还需要做两处小的调整。

首先在Users控制器中添加对store的调用:

   1:  Ext.define('AM.controller.Users', {
   2:      extend: 'Ext.app.Controller',
   3:      stores: [
   4:          'Users'
   5:      ],
   6:      ...
   7:  });

然后更新app/view/user/List.js,添加对store的引用:

   1:  Ext.define('AM.view.user.List' ,{
   2:      extend: 'Ext.grid.Panel',
   3:      alias : 'widget.userlist',
   4:   
   5:      //we no longer define the Users store in the `initComponent` method
   6:      store: 'Users',
   7:   
   8:      ...
   9:  });

在控制器中引用store的目的是动态的调用store定义页,并为调用的store赋上一个简短的storeId。这使在视图中引用store更加方便(在上例中只是添加了一个属性 store: 'Users')。

现在我们是将字段(name和email)定义在store中。这样也可以工作了,但是ExtJS4提供了一个很有用的类Ext.data.Model来帮助我们。我们将使用Model再次重构我们的代码,Model定义于app/model/User.js中:

   1:  Ext.define('AM.model.User', {
   2:      extend: 'Ext.data.Model',
   3:      fields: ['name', 'email']
   4:  });

完成model的定义后,需要在控制器和store中添加对Model的引用,并从store去掉对应字段的声明:

   1:  //the Users controller will make sure that the User model is included on the page and available to our app
   2:  Ext.define('AM.controller.Users', {
   3:      extend: 'Ext.app.Controller',
   4:      stores: ['Users'],
   5:      models: ['User'],
   6:      ...
   7:  });
   8:   
   9:  // we now reference the Model instead of defining fields inline
  10:  Ext.define('AM.store.Users', {
  11:      extend: 'Ext.data.Store',
  12:      model: 'AM.model.User',
  13:   
  14:      data: [
  15:          {name: 'Ed',    email: 'ed@sencha.com'},
  16:          {name: 'Tommy', email: 'tommy@sencha.com'}
  17:      ]
  18:  });

我们所做的重构工作不会马上产生效果,不过会有助于下一环节的工作。再次刷新页面运行应用会发现并无任何变化。不过是时候完成编辑功能了。

在Model中保存数据


现在我们有一个用户信息列表了,也可以双击记录打开编辑窗口了。接下来需要实现的任务就是保存用户编辑结果。现在我们的用户信息编辑窗口有一个表单和一个保存按钮“save”。接下来我们需要调整控制器的init函数,添加一个对“save”按钮的监听:

   1:  Ext.define('AM.controller.Users', {
   2:      init: function() {
   3:          this.control({
   4:              'viewport > userlist': {
   5:                  itemdblclick: this.editUser
   6:              },
   7:              'useredit button[action=save]': {
   8:                  click: this.updateUser
   9:              }
  10:          });
  11:      },
  12:   
  13:      updateUser: function(button) {
  14:          console.log('clicked the Save button');
  15:      }
  16:  });

我们在控制器中添加了第二个ComponentQuery选择器:‘'useredit button[action=save]'’。它和第一个选择器工作模式相同,首先根据xtype‘useredit’找到我们定义的用户信息编辑窗体,然后在窗体中查找action属性为‘save’的按钮。在我们定义用户信息编辑窗体类时,我们给“save”按钮设置action:’save’属性就给我们提供了一个可以快速定位到这个按钮的方法。

我们很高兴看到在我们点击save按钮时updateUser函数被调用并执行了。

我们已经将save按钮点击事件的监听与处理完成了。接下来要做的就是完善updateUser这个函数,真正实现用户信息的编辑。在updateUser函数中我们需要从表单中获取信息并保存到用户信息store中。让我们看看功能是怎样实现的:

   1:  updateUser: function(button) {
   2:      var win    = button.up('window'),
   3:          form   = win.down('form'),
   4:          record = form.getRecord(),
   5:          values = form.getValues();
   6:   
   7:      record.set(values);
   8:      win.close();
   9:  }

这里需要打断一下做些说明。通过按钮的点击事件我们获取了对‘save’按钮的引用,但是我们真正需要的是包含数据的表单及用户信息编辑窗体。为了更快的解决问题我们再次使用了ComponentQuery的选择器,首先使用button.up('window')获取了用户信息编辑窗体,而后使用win.down('form')获取了表单。

这之后我们要做的工作就很简单了,获取加载到表单中的record,并用用户编辑后的信息更新record。最后关闭窗体,回到用户信息列表上。下图是应用运行后的结果,我们将第一条记录的姓名改为了“Ed Spencer”:

保存记录到服务器上


刚刚的工作很简单吧。我们还需要完成最后一步——实现与服务器端的交互。之前我们只是生硬地将用户信息写在store中,接下来我们将尝试使用Ajax获取用户信息:

   1:  Ext.define('AM.store.Users', {
   2:      extend: 'Ext.data.Store',
   3:      model: 'AM.model.User',
   4:      autoLoad: true,
   5:   
   6:      proxy: {
   7:          type: 'ajax',
   8:          url: 'data/users.json',
   9:          reader: {
  10:              type: 'json',
  11:              root: 'users',
  12:              successProperty: 'success'
  13:          }
  14:      }
  15:  });

这里我们去掉了data属性,取而代之的是proxy属性。proxy是Extjs4中获取和保存数据的一种方式。ExtJS4中有多种形式的proxy,这里我们使用了比较简单的ajax proxy,我们告诉它从'data/users.json'中获取信息。

从上面的代码中看到,我们给proxy提供了一个reader对象。reader的作用是解码服务器端反馈的数据集信息。这次我们使用的是JSON Reader,并设置了它的root和successProperty属性。最后我们还需要创建一个'data/users.json'文件,将我们以前使用的数据复制进去:

   1:  {
   2:      success: true,
   3:      users: [
   4:          {id: 1, name: 'Ed',    email: 'ed@sencha.com'},
   5:          {id: 2, name: 'Tommy', email: 'tommy@sencha.com'}
   6:      ]
   7:  }

在store中的另一处改动是将autoLoad属性设置为true。这意味着stroe会主动向proxy发出请求加载数据。现在我们刷新页面重新加载应用并不能看到任何变化。但是实际上获取数据的方式已经不一样了。

我们要做的最后一件事就是将对数据所做的改变返回到服务器上。在我们这个例子中我们是使用静态的JSON文件在服务器端存储数据,所以我们不能看到任何数据库的变化。但是至少我们可以验证应用是在正常工作的。首先我们需要对store的proxy做出一点小的调整告诉它将更新信息发送到另一个url:

   1:  proxy: {
   2:      type: 'ajax',
   3:      api: {
   4:          read: 'data/users.json',
   5:          update: 'data/updateUsers.json'
   6:      },
   7:      reader: {
   8:          type: 'json',
   9:          root: 'users',
  10:          successProperty: 'success'
  11:      }
  12:  }

我们仍然会从users.json中获取数据,但是所有的更新都会发送到updateUsers.json。这只会返回一个虚拟的相应,让我们知道应用在正常运行。updateUsers.json中的内容是{"success": true}。然后还要做的就是告诉Store在编辑完成后同步一次记录,为此我们还要在updateUser函数中添加一行代码:

   1:  updateUser: function(button) {
   2:      var win    = button.up('window'),
   3:          form   = win.down('form'),
   4:          record = form.getRecord(),
   5:          values = form.getValues();
   6:   
   7:      record.set(values);
   8:      win.close();
   9:      this.getUsersStore().sync();
  10:  }

现在我们的这个示例应用已经完成了。我们再运行这个应用一次,编辑一条记录,点击保存按钮,然后查看request是否正确的发送给了updateUser.json文件:

示例应用account_manager的源码可在ExtJS4的文档中找到,所在目录是examples/app/simple。

作者注:本文译自Extjs4.0文档中的《MVC Architecture》一文。限于在下的英文水平及对Ext的理解,所以难免有些不足之处。不过是抱着自己学习也方便大家的心思,抛砖引玉勉强翻译了全文。如果有不通之处还请及时指正。

ExtJS MVC结构的更多相关文章

  1. ExtJS MVC学习手记 2

    开发环境 eclipse(indigo) ExtJS4.0 开发目标 使用store.model和controller创建菜单树 开发步骤 之前我们已经建立了一个MVC的项目框架.现在要做的就是在这个 ...

  2. ExtJS MVC学习手记

    开始学习ExtJS的MVC了.这篇文章仅是用来做一个目录,为自己这个阶段的学习内容做个索引. 手记涉及的文章: EXTJS MVC结构(译自ExtJS4.0文档中的<MVC Architectu ...

  3. Extjs MVC开发模式详解

    Extjs MVC开发模式详解   在JS的开发过程中,大规模的JS脚本难以组织和维护,这一直是困扰前端开发人员的头等问题.Extjs为了解决这种问题,在Extjs 4.x版本中引入了MVC开发模式, ...

  4. ExtJS MVC学习手记 1

    开发环境: ExtJS4.2 eclipse indigo 开发目标  搭建项目框架,创建viewport 开发步骤说明 这次主要使用extjs4的mvc模式创建viewport.籍此初步了解mvc模 ...

  5. Extjs MVC模式开发,循序渐进(一)

    本文讲述extjs mvc的Helloworld,tabPanel,event,页面布局layout等内容. 本页包含:MVC模式案例(一)~MVC模式案例(六),从搭建extjs mvc到点击按钮生 ...

  6. Extjs MVC学习随笔01

    Extjs Mvc模式下的整个MVC框架体系即下图: 包含了Controller(实现方法层),Store(数据来源管理层),View(页面布局层).之所以用MVC我想是因为减轻针对某一页面的单一的J ...

  7. MVC结构

    MVC结构是其它三个经典的设计模式的演变:观察者模式(Observer)(Pub/Sub), 策略模式(Strategy)和组合模式(Composite).   来自为知笔记(Wiz)

  8. 关于MVC结构

    简单的记录,只是想记录一下现在对MVC的理解. MVC,即模型(MODEL),视图(VIEW),控制器(CONTROLLER) 模型是数据模型 视图是图形界面 控制器是在两个之间的控制部分,用来将数据 ...

  9. 更加清楚理解mvc结构

      更加清楚理解mvc结构 文章来源:刘俊涛的博客 地址:http://www.cnblogs.com/lovebing 欢迎关注,有问题一起学习欢迎留言.评论.

随机推荐

  1. MongoDB 2: 安装和使用

    导读:上篇博客中简单介绍了MongoDB,本篇文章主要是介绍Mongo的安装和使用(环境为win8).(PS:这是一篇没什么技术含量的文章,仅是个人的笔记式文档)下一篇博客,将介绍Mongo使用过程中 ...

  2. ubuntu下,apt的参数使用,很实用呦

    ubuntu下apt-get 命令参数 常用的APT命令参数 apt-cache search package 搜索包 apt-cache show package 获取包的相关信息,如说明.大小.版 ...

  3. WWF3自定义活动<第八篇>

    WWF提供了对原有活动进行扩展以及自定义新活动的功能,用户可以通过"Workflow Activity Library"创建和开发自定义活动. 一.自定义活动类型 默认情况下,创建 ...

  4. 【缓存】.net中Cache管理操作

    隐藏行号 复制代码 ? 这是一段程序代码. using System; using System.Web; using System.Web.Caching; using System.Collect ...

  5. 查找Safari相关迹证

    日前有取证的同好提及Safari,想了解详细步骤,因而在此再补充说明相关. 除了Winodws外,Mac OS X也有为数不少的使用者,以下便以OS X自带的Safari浏览器为例,来查看有哪些重要迹 ...

  6. oracle 创建修改 job

    ---停止job 25是建立的job begin dbms_job.broken(,true); commit; end; --启动job begin dbms_job.run(); commit; ...

  7. 搭建高性能计算环境(九)、应用软件的安装之gaussian 09

    高斯软件一般使用的都是编译好的二进制版,所以解压缩后设置一下环境变量就可以用了. cd /opt tar xvf g09.tar.gz 设置环境变量,添加到/etc/profile文件中,重新登录后生 ...

  8. c#学习之Socket网络编程

    我是新手以前没写过博客 希望大家勿喷, 在编写Socket的时候需要导入System.Net.Socket 命名空间.利用该类我们可以直接编写Socket的客户端和服务的的程序了, 这里我们只讲tpc ...

  9. SQL Server 基础:Case两种用法

    测试数据 1).等值判断->相当于switch case select S#,C#,C#=( case C# when 1 then '语文' when 2 then '数学' when 3 t ...

  10. python实现决策树

    1.决策树的简介 http://www.cnblogs.com/lufangtao/archive/2013/05/30/3103588.html 2.决策是实现的伪代码 “读入训练数据” “找出每个 ...