ExtJS前端工作描述

  1. 云栖社区>
  2. 博客>
  3. 正文

ExtJS前端工作描述

pandamonica 2017-12-31 14:11:26 浏览1326
展开阅读全文

今天是17年12月31日,看来今天要在公司跨年了。
经过之前两周的测试,
1---成功的为自己的spring项目配置了hibernate作为持久化层的工具。也就是说,不需要使用Spring JDBC进行数据库的操作。直接使用Spring的一个模块,名字叫做Spring-orm,它是对Hibernate的集成模块。我们的java代码可以通过Spring-orm集成Hibernate,从而使用统一的Dao去进行持久化工作,与数据库打交道。

2---Service层的java代码,还是在Dao文件的基础上进行编写,具体还没有写,肯定要参考奎克系统的代码。

3---web层已经在Spring-MVC的框架下,使用json作为传递参数的媒介,虽然其中的道理还没有搞清楚,好在可以用了。

4---顺便开通了码云,使用eclipse以及它事先自带的插件egit,把代码传递到码云上,看上去高大很多,哈哈哈

下面的工作,就是前端。

我们需要完整的采用ExtJS负责前端所有的工作,然后前端与SpringMVC之间通过json相互交互。

好的,工作开始。
前端利用ExtJS,平时编码就是eclipse上手动编码,完全写完以后,用sencha命令行的命令,弄一下,相当于打个包。
ExtJS的入口
_

<!DOCTYPE HTML>
<html manifest="">
<head>
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1, maximum-scale=10, user-scalable=yes">
    <title>导航页</title>
    <script id="microloader" data-app="3054602d-f709-4e7b-b04c-099e1040034c" type="text/javascript" src="bootstrap.js"></script>
</head>
<body></body>
</html>

关键是这个index文件的代码

上面是一些无关紧要的描述,下面进入正题:
ExtJS对我来说是一个全新的内容,因此应该先去官网看看代码的写法和基本概念,url是 http://docs.sencha.com/extjs/6.2.0/
Ext4中使用的是MVC的概念,Ext5开始使用MVVM的概念,Ext6.2自然也是两者并存了。
_
doc网页的页面如上图所示,分了若干门类。我必须说,ExtJS的英文文档,都是十分基础的英文,真的可以看懂,大概讲述了如下内容:

js最大的特点就是flexibility 以及 classless,解决同一个问题,有不同的技术和编码style。但是假如你的js代码没有统一的格式,那么你的代码 can be difficult to understand, maintain, and re-use.
ExtJS的价值就是,Class-based programming,保留js语言特性的有点,同时面向对象编程。

1--Naming Conventions 命名规则(命名空间和文件路径之间的关系)
2--Declaration 定义新的类

3--ExtJS的UI部分,是一大堆component,这些component全部都是Ext.Component类的子类,全部都是。Ext的所有component都拥有生命周期的概念。lifecycle management including instantiation, rendering, sizing and positioning, and destruction. 也就是说ExtJS的UI部分的所有component,都拥有上述这些概念。ExtJS的UI部分提供了很多现成的component,马上就可以直接用。

Container是一种特殊的component,它是个容器,可以存放其他的component。好的Container不多说了,就说这么多。

4--XTypes and Lazy Instantiation
Every Component has a symbolic name called an xtype.
如果你写的ExtJS程序很大,或者说你的网页内容特别丰富,那就意味着并不是从第一秒开始,不是所有的component都要第一秒钟实例化、初始化,肯定是鼠标点击到哪里,哪里才开始发挥作用。xtype就是因此派上用场的。 这个概念就是lazy instantiation。
下面的代码,是聪明的,lazy instantiation

Ext.create('Ext.tab.Panel', {
    renderTo: Ext.getBody(),
    height: 100,
    width: 200,
    items: [
        {
            // Explicitly define the xtype of this Component configuration.
            // This tells the Container (the tab panel in this case)
            // to instantiate a Ext.panel.Panel when it deems necessary
            xtype: 'panel',
            title: 'Tab One',
            html: 'The first tab',
            listeners: {
                render: function() {
                    Ext.MessageBox.alert('Rendered One', 'Tab One was rendered.');
                }
            }
        },
        {
            // xtype for all Component configurations in a Container
            title: 'Tab Two',
            html: 'The second tab',
            listeners: {
                render: function() {
                    Ext.MessageBox.alert('Rendered One', 'Tab Two was rendered.');
                }
            }
        }
    ]
});

下面的代码是愚蠢的:

var childPanel1 = Ext.create('Ext.panel.Panel', {
    title: 'Child Panel 1',
    html: 'A Panel'
});

var childPanel2 = Ext.create('Ext.panel.Panel', {
    title: 'Child Panel 2',
    html: 'Another Panel'
});

Ext.create('Ext.container.Viewport', {
    items: [ childPanel1, childPanel2 ]
});

原因是,相当于第一秒钟就定义(声明并初始化)了所有的ui变量。

5--Creating Custom Components
我们自己写ExtJS的UI部分代码的时候有两种选择,1直接实例化一个ExtJS现成的component或者2extend一个现成的ExtJS的component
官方文档推荐你去extend一个,和你头脑中页面最接近的那个component。原因是ExtJS提供的自动生命周期管理特性:This is because of the automated lifecycle management Ext JS provides which includes(包括:) automated rendering when needed, automatic sizing and positioning of Components when managed by an appropriate layout manager, and automated destruction on removal from a Container.

6--Template Methods

An example is the render function. render is a method defined in Component. It is responsible for initiating the rendering phase of the Component lifecycle. render must not be overridden, but it calls onRender during processing to allow the subclass implementor to add an onRender method to perform class-specific processing. Every onRender method must call its superclass' onRender method before "contributing" its extra logic.

7--选哪个component去继承呢?
说了这么多,我们这些写代码的,有哪些component可以用呢?

选一个合适的component去extend可以让你事半功倍。
在ExtJS的编码历史中,有一个时期,不论写什么样的网页大家都爱全都去extend Ext.panel.Panel 类,认为这样做就简单了。但事实上并非如此,如果你的网页中的各个块,不需要工具栏、页脚的按钮或者component中没有其他元素的话,你全都用Ext.panel.Panel 类就是一种巨大的浪费。

如果你的UI component不需要包含其他的component,那最好你就直接extend Ext.Component

如果你的UI component需要包含其他component,而且不需要工具栏之类的功能,那就extend Ext.container.Container

如果你的UI component需要工具栏、头、尾之类的,那你就继承 Ext.panel.Panel

8--Container 的 Layout
ExtJS中Container是一种特殊的component,container中包含了多个component,因此需要layout决定他们之间的位置关系。

9--Data Package 数据包?
反正就是ExtJS代码中,load and save 你数据的东西。
save:Ext--->其他地方
load:Ext<---其他地方
Data Package包含很多类,比如:model store 和proxy

Model
A Model represents an entity in an application.
Ext.data.Model是ExtJS中Data Package的核心概念,
_

Proxy有两种:
Proxies are used by Models and Stores to handle the loading and saving of Model data. There are two types of proxies: Client and Server.

它俩的学名分别是 Ext.data.proxy.Client 和 Ext.data.proxy.Server.

但是client proxy基于html5,server proxy比较常见吧。
Proxies can be defined directly on the schema of the Model's base class .
The Client proxies save their data locally.
The Server proxies save their data by sending requests to some remote server.
看来我们需要使用的,是Ext.data.proxy.Server
_

Proxy工作的原则就是,它的工作仅限于并必须是 增删改查四种操作的一种。

Stroe
Models are typically used with a Store, which is basically a collection of records

9--事件

Ext.create('Ext.Panel', {
    html: 'My Panel',
    renderTo: Ext.getBody(),
    listeners: {
        afterrender: function() {
            Ext.Msg.alert('Success!', 'We have been rendered');
        }
    }
});

10--components
_
有很多现成的a wide range of useful Components out of the box
学学英语也不错

11--Application Architecture
ExtJS同时支持MVC和MVVM,二者有区别,但是目的都是把代码分布到不同的js文件中。focus on dividing application code along logical lines。

In an MVC architecture, most classes are either Models, Views or Controllers. The user interacts with Views, which display data held in Models. Those interactions are monitored by a Controller, which then responds to the interactions by updating the View and Model, as necessary.

The View and the Model are generally unaware of each other because the Controller has the sole responsibility of directing updates. Generally speaking, Controllers will contain most of the application logic within an MVC application. Views ideally have little (if any) business logic. Models are primarily an interface to data and contain business logic to manage changes to said data.

MVC这种结构,就是让他们各司其职,然后让整个js代码容易维护。

MVVM结构,VM代表view model,它出现在View 和Model之间,负责数据绑定data binding。
具体的内容还是看代码吧。
至于代码结构,之前也说了app.js啦,application.js啦很多,ExtJS是有固定代码结构的。
http://docs.sencha.com/extjs/6.2.0/guides/application_architecture/application_architecture.html
这一部分真的值得好好看一下,必须要看的。

View
A view contains all of your application's visual aspects.
View就是ExtJS中UI部分,各种component和container,View几乎只负责页面的显示。
Controller部分在ExtJS5之前,也就是ExtJS4的年代,最为人诟病的就是:Controller资源没有被回收(destroyed),或者一个Controller操作多个View
但是ExtJS 5时期,有了ViewController这个概念,ViewController与View的关系就是一对一的关系。ViewController相当于View的私家event handler的容器。
ExtJS5的ViewController相当于对传统Controller的补充。

The ViewModel, like ViewController, is owned by the view that references it.

Models and Stores make up the information gateway of your application. Most of your data is sent, retrieved, organized, and "modeled" by these two classes.

A Store is a client side cache of records (instances of a Model class). Stores provide functions for sorting, filtering and querying the records contained within.

A Ext.data.Model represents any type of persist-able data in your application. Models are most commonly used in conjunction with stores. Stores can then be consumed by data-bound components like grids, trees, and charts.

We have added support for ViewModels and MVVM as well as ViewControllers to enhance MVC applications. Best of all, these choices are not mutually exclusive, so you can introduce these features incrementally or even blend them.

ExtJS在6.x中添加了ViewModel,也就是MVVM的支持。
而更早的ExtJS5时期添加的ViewController,相当于对早期MVC架构的补充。

也就是说
MVVM --- ViewModel ExtJS 6
MVC --- ViewController ExtJS 5
这是两个不同范畴,不同阶段的概念。

在ExtJS4的阶段,MVC实现大型application的时候遇到了很多问题:多个码农一起写一个网站项目的时候,很难保证,controller准确的去监听和响应自己设计的那个view。因为大家都在改代码。虽然lazy Installization可以让一些资源只有被唤起的时候才加载,但是传统controller是无法被destroyed的。

ExtJS5开始,引入了ViewController来解决上述问题(一种折中的方式,向旧版本兼容MVC的方式),ViewController可以解决:

  1. Simplifies the connection to views using “listeners” and “reference” configs.
  2. Leverages the life cycle of views to automatically manage their associated ViewController.
  3. Reduces complexity in the ViewController based on a one-to-one relationship with the managed view.
  4. Provides encapsulation to make nesting views reliable.
  5. Retains the ability to select components and listen to their events at any level below the associated view.

比如销毁的问题,和一对一的问题。
最终的结论就是:
We think ViewControllers will greatly streamline your MVC applications.
ViewController可以高效的组织你的MVC应用。
ViewController与MVVM的概念没有关系,ViewController是ExtJS5提出的概念,目的是解决ExtJS4中Controller的一些问题。
MVVM的概念提出于ExtJS6。

ViewModel的概念与Data Binding是一起出现的,它是与View关联在一起的,很可能也是一对一的关系。

ViewModel这个概念power了Data Binding,ViewModel和Data Binding这两个概念,是ExtJS 6 中的强力补充。它们的作用就是让程序员少写代码,而且让代码在MVVM的概念上更加清晰的分开,易于维护。

互相之间远近关系如下:

码农---Component----ViewModel----data

优先级: 被bind上的Component的configuration properties,要优先于static值。

One of the most helpful parts of binding is that all of the children of the component with a viewModel also have access to their container's data.

子component可以访问Container的viewModel数据。
如下所示:

Ext.create('Ext.panel.Panel', {
    title: 'Simple Form',

    viewModel: {
        type: 'test'
    },

    layout: 'form',
    defaultType: 'textfield',

    items: [{
        fieldLabel: 'First Name',
        bind: '{firstName}' // uses "test" ViewModel from parent
    },{
        fieldLabel: 'Last Name',
        bind: '{lastName}'
    }]
});

双向绑定:two way binding
之前的数据绑定,都是将model的中的数据提供给view,单方向
现在view中显示的数据,比如输入框Input,input中的数据修改了以后,绑定的viewmodel中的对应内容也会同步发生变化。
这就是双向绑定。

下面我是官网给出的例子

Ext.define('MyApp.view.TestViewModel', {
    extend: 'Ext.app.ViewModel',

    alias: 'viewmodel.test', // connects to viewModel/type below

    data: {
        firstName: 'John',
        lastName: 'Doe'
    },

    formulas: {
        // We'll explain formulas in more detail soon.
        name: function (get) {
            var fn = get('firstName'), ln = get('lastName');
            return (fn && ln) ? (fn + ' ' + ln) : (fn || ln || '');
        }
    }
});

Ext.define('MyApp.view.TestView', {
    extend: 'Ext.panel.Panel',
    layout: 'form',

    // Always use this form when defining a view class. This
    // allows the creator of the component to pass data without
    // erasing the ViewModel type that we want.
    viewModel: {
        type: 'test'  // references alias "viewmodel.test"
    },

    bind: {
        title: 'Hello {name}'
    },

    defaultType: 'textfield',
    items: [{
        fieldLabel: 'First Name',
        bind: '{firstName}'
    },{
        fieldLabel: 'Last Name',
        bind: '{lastName}'
    },{
        xtype: 'button',
        text: 'Submit',
        bind: {
            hidden: '{!name}'
        }
    }]
});

Ext.onReady(function () {
    Ext.create('MyApp.view.TestView', {
        renderTo: Ext.getBody(),
        width: 400
    });
});

最后描述一下Model Proxy Store
在extjs官网的右上方,可以搜索
如下图所示
_
ExtJS 6以后 有两类应用场景:modern 和 classic
modern用于手机、pad这类移动设备上的触摸屏。
classic用于pc上的显示器+键盘+鼠标的传统交互方式(也就是网站)。
我们目前的工作,还是普通网站,因此在搜索的时候要选中classic,也就是让那个大个儿的C字母底色变成白色,然后输入想要搜索的关键词。
比如上图,我们搜索model,会弹出来一个列表,列表左侧提示这个item的身份:class或者config
我们想要看的当然是class
所以选中第一个
_
Model的学名叫做:Ext.data.Model。Model是extjs对实际事物的建模,比如用户、订单、产品。
Models are used by Ext.data.Store, which are in turn used by many of the data-bound components in Ext.
Component使用Store,Store使用Model。
下面一段我就没必要翻译了:
Using a Proxy

Models are great for representing types of data and relationships, but sooner or later we're going to want to load or save that data somewhere. All loading and saving of data is handled via a Ext.data.proxy.Proxy, which can be set directly on the Model:

Ext.define('User', {
    extend: 'Ext.data.Model',
    fields: ['id', 'name', 'email'],

    proxy: {
        type: 'rest',
        url : '/users'
    }
});

上面定义了一个Model,Model中有一个rest类型的proxy,这个proxy的学名叫做: Ext.data.proxy.Rest

下面是它的被使用的方法:

var user = Ext.create('User', {name: 'Ed Spencer', email: 'ed@sencha.com'});

user.save(); //POST /users

新建一个Model的实例,然后调用它的save方法,意味着:告诉rest类型的proxy,我们想把Model的数据持久化到数据库。
proxy,因为我们使用save方法,proxy知道了我们(码农)的意图以后,首先判断出来这个model的数据还没有被持久化过(因为id,类似于hibernate中的OID),这不重要,重要的是proxy将要 issue a POST request to the url we configured (/users)。
上述过程就是将extJS上的(网页上的,内存中的)数据持久化到指定地址的过程。
load数据的过程也是类似的(从数据库读取数据到内存):

//Uses the configured RestProxy to make a GET request to /users/123
User.load(123, {
    success: function(user) {
        console.log(user.getId()); //logs 123
    }
});
//去   url   /user/123这个地址获取数据

Model擅长或者被用来表示 数据或者关系(实体和关系)的类型,但是我们迟早要加载数据(从数据库读数据到ExtJS的代码)或者保存数据(从ExtJS的代码到数据库),上述两个操作是Proxy的工作,Proxy的学名叫做Ext.data.proxy.Proxy
_
我们可以看到Ext.data.proxy.Proxy是一个alias,它的样子如下
_

Store使用proxy对Model所代表的对象的数据进行load或者save。

好深刻的一句话。
下面看看Store怎样通过proxy对Model进行操作(Model上配置了Proxy)
我们的网页,也就是ExtJS的View部分的UI的Component,常常会负责显示一些数据。这些数据原本存放在硬盘的数据库上,显示的时候呢,需要load那些数据库中的数据,到Model的实例中。
ExtJS的做法,首先创建一个Store

Ext.define('User', {
    extend: 'Ext.data.Model',
    fields: ['id', 'name', 'email'],

    proxy: {
        type: 'rest',
        url : '/users'
    }
});

var store = Ext.create('Ext.data.Store', {
    model: 'User'
});

//uses the Proxy we set up on Model to load the Store data
store.load();

A Store is just a collection of Model instances.

下面去Store的Doc看看好了
_

 // Set up a model to use in our Store
 Ext.define('User', {
     extend: 'Ext.data.Model',
     fields: [
         {name: 'firstName', type: 'string'},
         {name: 'lastName',  type: 'string'},
         {name: 'age',       type: 'int'},
         {name: 'eyeColor',  type: 'string'}
     ]
 });

 var myStore = Ext.create('Ext.data.Store', {
     model: 'User',
     proxy: {
         type: 'ajax',
         url: '/users.json',
         reader: {
             type: 'json',
             rootProperty: 'users'
         }
     },
     autoLoad: true
 });

In the example above we configured an AJAX proxy to load data from the url '/users.json'. We told our Proxy to use a Ext.data.reader.Json to parse the response from the server into Model object - Ext.data.reader.Json for details.

网友评论

登录后评论
0/500
评论
pandamonica
+ 关注