ExtJS从头开始(第1部分)


欢迎来到新的博客系列“ExtJS从头开始”的第一部分。为什么要写这个系列?嗯,在不断收到客户有关ExtJS学习曲线的反馈后,发现他们在学习ExtJS时所面临的挑战之一是缺乏基础知识,或者是没了解过ExtJS是如何运作的,他们只是学习了一种模式之后就开始了。

在本系列中,将解释清楚ExtJS是如何以及为什么是这样运作的,而这,将通过一些简单的例子来说明。在这一系列文章中,将建立一个功能齐全的ExtJS应用程序,也就是所谓的“从头开始”。

以下是本系列文章的源代码访问地址:
https://github.com/mgusmano/ExtJSFromScratchg

让我们开始吧!

从最简单的HTML5的Web应用程序开始是最好不过的方式。HMTL5的Web应用程序是面向数据的,包含以下三个方面:

  • HMTL:用来告诉Web浏览器如何去绘制内容的“标记”
  • CSS:层叠样式表,用来指示浏览器如何去样式化HTML标签(字体、颜色等等)
  • Javascript:用于维护HTML的程序语言,实际上,在浏览器中被称为DOM或文档对象模型。

以下被命名为index.html的文件,是一个简单的HTML5应用程序。要注意的是,缩进和间距是虽然不是必须的,但很好的使用他们,可以使内容具有更好可读性。

基本Web页面:

    <!DOCTYPE HTML>
    <html>
     <head>
      <title>Ext JS From Scratch - Part 1, Demo 1</title>
      <link href='theme.css' rel='stylesheet'/>
      <script src='Ext-lite.js'></script>
      <script src='app.js'></script>
     </head>
     <body>
      <div id="ext-viewport" class="x-viewport">
       <div id="ext-grid1" class="x-grid">
        <div class="gridTitle">Users</div>
         <table id="ext-table1" class="blueTable">
          <thead>
           <th>Name</th><th>Email Address</th><th>Phone Number</th>
          </thead>
          <tbody>
           <tr>
            <td>Lisa</td><td>lisa@simpsons.com</td><td>555-111-1224</td>
           </tr>
           <tr>
            <td>Bart</td><td>bart@simpsons.com</td><td>555-111-1224</td>
          </tr>
          <tr>
           <td>Homer</td><td>homer@simpsons.com</td><td>555-111-1224</td>
          </tr>
          <tr>
           <td>Marge</td><td>marge@simpsons.com</td><td>555-111-1224</td>
          </tr>
         </tbody>
        </table>
       </div>
      </div>
     </body>
    </html>

下面来分析一下这个文件,它可以被分解为一组开始和结束的HTML标签:

  • 第1行表示该文件是一个HTML5文件
  • 第2行和第35行是开始和结束的html标记,在html标签内是head和body标签
  • 第3~8行是head标签,它包含了3个文件(目前是空的)的引用,这些文件将用来保存将要编写的CSS和JavaScript脚本
  • 第9行和第34行是body标记,它里面的其他标记用来高速浏览器将要显示什么或者使用JavaScript代码来注入更多标记(很快就会实现这个)。

在浏览器打开这个文件将会看到以下页面:

以上页面显示了一个网格,顶行是网格的标题,第二行是列标题,其余是网格的数据。对于这个页面,需要助于的是:首先,这个页面没有主题,它只是白色背景上的黑色文字;其次,页面是静态的,数据在页面上是硬编码。在常见的Web应用程序中,数据基本上是动态的,并且是基于服务器的数据,下面来解决这个问题。

使用CSS来创建主题

CSS一般是用来样式化或主题化应用程序。在theme.css,已经为HTML文件添加了以下样式,刷新浏览器将看到结果。

    .x-viewport {
      margin: 0; border: 5px solid green;
      width: 100%; height: 100%; right: 0; top: 0;
      overflow: hidden;
      position: absolute; box-sizing: border-box;
    }

    .x-grid {
      font-family: Roboto, sans-serif;
      font-weight: 400;font-size: 18px; width: 100%;
    }

    .gridTitle {
      position: absolute;
      top: 0;right: 0;bottom: 0;left: 0;
      display: flex;
      align-items: center;
      justify-content: center;
      background: #2196f3; color: #FFFFFF;
      height: 48px;
    }

    .blueTable {
      margin-top: 48px;
      border-collapse: collapse;
      font-weight: 100;font-size: 14px; width: 100%;
    }

    .blueTable td, .blueTable th {
      border: 1px solid #E6E6E6; padding: 10px;
    }

    .blueTable th {
      font-weight: 600;text-align: left;
    }

浏览器的显示结果:

要创建工作良好的和跨浏览器工作的CSS并不容易。在后续文章中将会看到Ext JS带有一整套的主题,而这些主题可以很容易对他们进行修改。

使用Javascript让页面充满生机

现在,让我们来解决页面上的交互问题,如事件(如单击一行),以及在网格中使用静态的数据标签。实际上,在页面body内的html标签都是静态标签。幸运的是,使用Javascript可以对页面中的任何部分进行操作,并可以动态的绘制页面,而这,就是一个框架所要租殴打事情,因而,我们来观察一下以下两个步骤:

步骤1:在Ext-lite.js内,包含了一些框架代码,将这些代码定义为框架代码意味着这些代码对于任何一个应用程序来说都是相同的,而这包含了辅助函数和任何其他的不特定于应用程序自身的代码。

对于第一次迭代,包含了表格中每一行的单击事件的代码(addRowHandlers),还添加了等待DOM内容加载后(表示页面已经准备好运行代码了)运行launch函数的代码。在launch函数中,就可以编写应用程序代码了:

    document.addEventListener("DOMContentLoaded", function(event) {
      launch();
    });



    function addRowHandlers(table, fn) {
      var table = document.getElementById(table);
      var rows = table.getElementsByTagName("tr");
      for (var i = 1; i < rows.length; i++) {
        var row = table.rows[i];
        var cols = row.getElementsByTagName("td");
        var o = {};
        for (var j=0;j<cols.length;j++) {
          o['c'+j]=cols[j].innerHTML;
        }
        var record=[];
        record[0] = {};
        record[0].data = o;
        row.onclick = function() {return fn(row,record)}; 
      }
    }

步骤2:在app.js的launch函数中,包含了调用addRowHandlers函数所需的代码。在这里,要清楚的一点是,在Ext-Lite.js文件内的框架代码只是提供给我们使用并让我们专注于应用程序开发的代码,我们的应用程序开发是在app.js中完成的,而不是在框架代码中。

    function launch() {
      console.log('page is loaded');
      addRowHandlers("ext-table1", onSelect);
    };

    function onSelect(sender, record) {
      var r = record[0].data;
      var text = r.c0+' - '+r.c1+' - '+r.c2;
      alert(text);
    };

刷新页面并单击Manger这一行,将看到如下输出:

最后,我们来解决body中的静态标签问题,正如上面所提到的,可以使用Javascript在页面中动态创建html。

观察一下静态HTML的的结构,会看到类似于以下的逻辑结构:

<body>
  <viewport>
    <grid>

视区(viewport )是每一个应用程序的公共部分,而网格自身包含一些动态项:

  • xtype:在Ext JS中,对象的类型被称作xtype
  • 标题(title):面板中页眉的内容
  • 列(columns):网格中所有列的描述
  • 数据(data):填充网格的数据
  • 侦听器(listeners):用来侦听对象事件的集合

是否可以删除页面中的静态HTML(允许框架使用Javascript来动态创建他们),并在launch函数中创建一个包含xtype、标题、列、数据和事件的逻辑“网格”作为视区的子对象呢?如以下代码:

{
  xtype: 'grid',
  title: 'Users',
  columns: [
    { name: 'Name' },
    { name: 'Email' },
    { name: 'Phone number' }
  ],
  data: data,
  listeners: {
    select: onSelect
  }
}

首先,需要添加一些功能到Ext-lite.js用来动态创建HTML,在以下地址可以查看这些代码:

https://github.com/mgusmano/ExtJSFromScratch/blob/master/Part01/03/Ext-lite.js

在Ext-list.js中会看到许多代码,这些代码是Ext JS框架用来表示代码类型的代码,你必须去编写这些代码,框架会为你提供这些代码。我们只需要在app.js的launch函数中编写代码,如以下看到的内容。

在index.html文件中会看到以下代码(注意,在body中没有任何标签):

    <!DOCTYPE HTML>
    <html>
     <head>
        <link href='theme.css' rel='stylesheet'/>
        <script src='Ext-lite.js'></script>
        <script src='app.js'></script>
     </head>
     <body></body>
    </html>

在app.js中,修改后的代码如下:

    function launch() {
      Viewport.add({
        xtype: 'grid',
        title: 'Users',
        columns: [
          {text: 'Name', width: 100, dataIndex: 'name'},
          {text: 'Email Address', flex: 1, dataIndex: 'email'},
          {text: 'Phone Number', width: 200, dataIndex: 'phone'}
        ],
        data: data,
        listeners: {
          select: onSelect
        }
      });
    }

    function onSelect(sender, record) {
      var r = record[0].data;
      var text = r.name+' - '+r.email+' - '+r.phone;
      alert(text);
    };

    var data = [
      { name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224' },
      { name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234' },
      { name: 'Homer', email: 'homer@simpsons.com', phone: '555-222-1244' },
      { name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254' }
    ]

现在,使用了一种只需定义所需的用户界面和要做什么的,而不需要知道如何构造HTML的方法来定义外观。对于创建一个应用程序来说,这相当的简单,而这,整数Ext JS的意义!

使用Ext框架来创建应用程序

现在(终于!),可以使用Ext JS的主题和框架库来替代现在的库了,最终的文件,请参阅https://github.com/mgusmano/ExtJSFromScratch/tree/master/Part01/05

对于这个示例,已经将Ext JS 6.5.2框架复制到名为6.5.2的文件夹。要使用这个,需要使用Ext JS的许可证版本或者获取一个框架的试用版本:https://www.sencha.com/products/extjs/evaluate

首先,在index.html文件,将第5行链接到Ext JS的主题“Material”主题(仿google的Material规范)。第6行链接的是Ext JS的现代工具包(该示例引用的是整个框架,在未来的本系列的博客文章中,将会看到如何更好的将Ext JS框架包含在应用程序中)。最终的index.html页面如下所示:

    <!DOCTYPE HTML>
    <html>
     <head>
      <title>Ext JS From Scratch - Part 1, Demo 5</title>
      <link href='ext-6.5.2/build/modern/theme-material/resources/theme-material-all-debug.css' rel='stylesheet'/>
      <script src='ext-6.5.2/build/ext-modern-all.js'></script>
      <script src='app.js'></script>
     </head>
     <body></body>
    </html>

在app.js中,唯一变化是将launch函数作为一个对象参数封装在一个 Ext.application的实例中(在未来的博客中将解释为什么要这样做):

    Ext.application({
      launch: function () {
        Ext.Viewport.add({
          xtype: 'grid',
          title: 'Users',
          columns: [
            {text: 'Name', width: 100, dataIndex: 'name'},
            {text: 'Email Address', flex: 1, dataIndex: 'email'},
            {text: 'Phone Number', width: 200, dataIndex: 'phone'}
          ],
          data: data,
          listeners: {
            select: onSelect
         }
        });
      }
    });

    function onSelect(sender, record) {
      var r = record[0].data;
      var text = r.name+' - '+r.email+' - '+r.phone;
      alert(text);
    };

    var data = [
      { name: 'Lisa', email: 'lisa@simpsons.com', phone: '555-111-1224' },
      { name: 'Bart', email: 'bart@simpsons.com', phone: '555-222-1234' },
      { name: 'Homer', email: 'homer@simpsons.com', phone: '555-222-1244' },
      { name: 'Marge', email: 'marge@simpsons.com', phone: '555-222-1254' }

    ]
    });

应用程序最终的效果如下:

就是它了——你的第一个事实上上的ExtJS应用程序!它比从头开始所创建的第一个应用程序功能更强大。ExtJS网格可以做的事包括排序、大数据处理、列隐藏和更多!如果对Grid还能用来做什么有兴趣,可以查看Kitchen Sink示例:

你所需要做的就是修改launch函数,其余的ExtJS框架会为来实现。

你可能会希望在这里写一个更复杂的应用程序。在这系列文章中,将会覆盖更多的东西,而到目前为止,已经有了很大进展。敬请关注即将推出的ExtJS从无到有系列之二。

作者:Marc Gusmano
原文:https://www.sencha.com/blog/ext-js-from-scratch-part-1/

译者:黄灯桥
译文:http://blog.csdn.net/tianxiaode/article/details/78609946