概述

·  ExtJs5能够搭建Js的MVC框架,通过配置路由能够通过左边树形菜单导航到所需的页面,效果如下:

搭建JS框架

  新建home.htm页面作为ExtJs加载的主体页面,页面引入ExtJs需要的JS和ExtJs入口Js文件app.js

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<title>ExtJS演示</title>
<script type="text/javascript" src="Ext/ext-all.js"></script>
<script type="text/javascript" src="Ext/ext-locale-zh_CN.js"></script>
<link rel="stylesheet" type="text/css" href="Ext/packages/ext-theme-crisp/build/resources/ext-theme-crisp-all_01.css">
<script type="text/javascript" src="app.js"></script>
</head>
<body>
</body>
</html>

  app.js是ExtJs框架的入口,新建ExtJs中Application程序,指定所有新建ExtJs类的命名空间必须是MyApp开头,类似 MyApp.***,另外在app.js同级目录下新建app文件夹,里面新建文件夹view和viewmodel,这些文件夹的命名和规则必须是确定,不能任意修改,否则文件加载的时候,找不到相应的Js文件;

//ExtJs的入口,加载该Js之后,自动调用launch方法内容项
Ext.application({
name : 'MyApp',
extend:'MyApp.Application',
autoCreateViewport:'MyApp.view.main.Main',
// controllers:['Users'],
listen: {
controller: {
'#': {
unmatchedroute: 'onUnmatchedRoute'
}
}
},
onUnmatchedRoute: function(hash) {
alert('Unmatched', hash);
},
init:function(){
var me=this;
me.setDefaultToken('all');
},
launch : function() {
}
});

在app目录下,新建Application.js,命名MyApp.Application,代码如下,切记定义Js组件的名称,必须和文件路径对应

Ext.define('MyApp.Application',{
extend:'Ext.app.Application',
name:'MyApp',
// stores:[
// 'UserStore@MyApp.store'
// ]
});

在app目录下,新建文件夹view\main,里面新建main.js,主要继承Ext.container.Container容器控件,负责页面布局使用,页面布局模式采用border使用,分为头部、导航、中间页面内容展示;

Ext.define('MyApp.view.main.Main',{
extend:'Ext.container.Container',
xtype:'app-main',
requires:['MyApp.view.main.MainController','MyApp.view.main.Header','MyApp.view.main.Navigation','MyApp.view.main.ContentPanel'],
controller:'main',
layout:{type:'border'},
items:[
{region:'north',xtype:'app-header'},
{region:'west',xtype:'app-navigation'},
{region:'center',xtype:'app-contentPanel'}
]
});

在app\view\main,新建总部内容MainController.js,类型是Ext.app.ViewController。内容如下,主要负责Main.js的Action和hander的绑定,控制页面的路由导航

var com={'message-view':'MyApp.view.message.MessageController','UserGrid':'MyApp.view.user.UserGridController'};
Ext.define('MyApp.view.main.MainController',{
extend:'Ext.app.ViewController',
requires:[
'Ext.window.MessageBox'
],
alias:'controller.main',
control:{
'app-navigation':{
selectionchange:'onTreeNavSelectionChange'
}
},
onTreeNavSelectionChange:function(selModel,records)
{
var record=records[];
console.log(record.getId());
if(record)
this.redirectTo(record.getId());
},
routes: {
':id': {
action: 'handleRout',
before: 'beforeHandleRout'
}
},
handleRout: function (id) {
console.log('Handle:'+id);
var me=this,
mainView = me.getView(),
navigationTree = mainView.down('app-navigation'),
contentPanel = mainView.down('app-contentPanel'),
store=navigationTree.getStore(),
node=store.getNodeById(id);
contentPanel.removeAll(true),
controlName=com[id];
Ext.create(controlName);//MyApp.view.message.MessageController
var module = Ext.apply({}, {
xtype: id,
itemId: id,
//glyph: node.get('glyph'),
title: node.get('text')
// tooltip: node.get('text')
});
contentPanel.add(module);
var text = node.get('text'),
title = node.isLeaf() ? (node.parentNode.get('text') + ' - ' + text) : text;
contentPanel.setTitle(title);
//Ext.suspendLayouts(); //暂停布局
Ext.resumeLayouts(true); //恢复布局
},
beforeHandleRout: function (id, action) {
//动态实例化controller
action.stop();
var me=this,
store=Ext.StoreMgr.get('NavigationStore');
node=store.getNodeById(id);
if(node)
{
action.resume();
}
else
{
Ext.Msg.alert(
'路由跳转失败',
'找不到id为' + id + ' 的组件. 界面将跳转到应用初始界面',
function() {
me.redirectTo('all');
}
);
action.stop();
}
},
});

在app\view\main,新建头部Header.js,内容如下

Ext.define('MyApp.view.main.Header',{
extend:'Ext.Container',
xtype:'app-header',
height:,
layout:{type:'hbox',align:'middle'},
items:[
{xtype:'component',html:'<h2>XX系统</h2>'},
{xtype:'component',html:'ExtJs实例',flex:}
]
});

在app\view\main,新建导航Navigation.js,内容如下,PS 树形结构的id名称要和视图的xtype对应

Ext.define("MyApp.view.main.Navigation",{
extend:'Ext.tree.Panel',
xtype:'app-navigation',
rootVisible:false,
userArrows:true,
// hideHeaders:true,
width:,
minWidth:,
split:true,
collapsible:true,
store:Ext.create('Ext.data.TreeStore', {
id:'NavigationStore',
root: {
expanded: true,
id:'all',
text:'All',
children: [
{text: "消息管理", id: "message-view", leaf: true},
{text: "用户列表", id: "UserGrid", leaf: true}
]
}
})
});

在app\view\main,新建总部内容ContentPanel.js,内容如下

Ext.define('MyApp.view.main.ContentPanel',{
extend:'Ext.panel.Panel',
xtype:'app-contentPanel',
autoScroll:true
});

在app\view\user,新建用户页面UserGrid.js,内容如下

Ext.define('MyApp.view.user.UserGrid', {
extend: 'Ext.grid.Panel',
xtype: 'UserGrid',
title: '用户列表',
requires:['MyApp.store.UserStore'],
store:Ext.create('MyApp.store.UserStore'),
controller:'usergrid',
initComponent:function(){
var me = this;
me.columns = [
{xtype: 'rownumberer',header: '序号', width: , align: 'center'},
{xtype: 'rownumberer',header: '用户名', width: , align: 'center'},
{xtype: 'rownumberer',header: '年龄', width: , align: 'center'},
];
me.callParent();
},
width: ,
height:,
border:true,
listeners:{
itemdblclick: {
fn: 'userClick',
scope: "controller"
}
}
});

在app\view\user,新建用户视图控制器UserGridController.js,内容如下

Ext.define('MyApp.view.user.UserGridController',{
extend:'Ext.app.ViewController',
alias:'controller.usergrid',
requires:["MyApp.view.user.UserGrid"],
userClick:function( view, record, item, index, e, eOpts){
alert('hello'+record.get('name'))
}
});

在app\model ,新建UserModel.js,内容如下

Ext.define('MyApp.model.UserModel', {
extend: 'Ext.data.Model',
fields: [
{name: 'name', type: 'string'},
{name: 'age', type: 'int'},
{name: 'phone', type: 'string'}
]
});

在app\store,新建UserStore.js,内容如下

Ext.define('MyApp.store.UserStore', {
extend: 'Ext.data.Store',
model: 'MyApp.model.UserModel',
autoLoad: true,
alias:'user-store',
proxy: {
type: 'ajax',
api: {
read: 'data/users.json'
},
reader: {
type: 'json',
rootProperty: 'users',
successProperty: 'success'
}
}
});

需要注意事项:

1、文件目录必须按Ext.define的定义的顺序建立,这个是默认约定的,否则找不到文件Js;

2、导航的id值必须是和新建的控件名称的xtype类型对应,否则加载控件失败;

3、ViewController和View绑定,在Js里面requires的内容项,默认会加载相应的Js文件;

4、如果提示,extjs Cannot read property 'isBufferedStore' of undefined,主要原因在于store内容为空导致的;

完整代码如下

DEMO下载

参考地址 Extjs5.0(6):控制器(Controller、ViewController)和路由器(Router)

ExtJS5搭建MVVM框架的更多相关文章

  1. “老坛泡新菜”:SOD MVVM框架,让WinForms焕发新春

    火热的MVVM框架 最近几年最热门的技术之一就是前端技术了,各种前端框架,前端标准和前端设计风格层出不穷,而在众多前端框架中具有MVC,MVVM功能的框架成为耀眼新星,比如GitHub关注度很高的Vu ...

  2. 前端MVVM框架设计及实现(一)

    最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了 借鉴的自然还是从正美的avalon开始了,我记得还是去年6月写过一个系列的av ...

  3. 整合MVVM框架(Prism)

    整合MVVM框架(Prism) 我们基础的框架已经搭建起来了,现在整合MVVM框架Prism,在ViewModel做一些逻辑处理,真正把界面设计分离出来. 这样方便我们系统开发分工合作,同时提高系统可 ...

  4. js架构设计模式——前端MVVM框架设计及实现(一)

    前端MVVM框架设计及实现(一) 最近抽出点时间想弄个dom模块化的模板引擎,不过现在这种都是MVVM自带的,索性就想自己造轮子写一个简单的MVVM框架了 借鉴的自然还是从正美的avalon开始了,我 ...

  5. 迷你MVVM框架 avalonjs 1.3.9发布

    本次升级,avalon改进了许多内部方法,大大提升性能,并且带来异步刷新视图的新功能. ms-html内部不再使用异步 head元素中的avalon元素加入ms-skip指令 重构计算属性,现在超级轻 ...

  6. [转]MVP+WCF+三层结构搭建项目框架

    最近,我一直在重构之前做的一个项目,在这个过程中感慨万千.原先的项目是一个运用了WCF的C/S系统,在客户端运用了MVC模式,但MVC的View.Model耦合以及WCF端分布式欠佳等问题让我有了重构 ...

  7. angularjs+requlirejs 搭建前端框架(1)

    第一部分:发发牢骚吧 随着富前端时代的逐渐深入,越来越多的前端技术框架层出不穷,可以说是百花齐放.让我们这些爱好前端的人疲于奔命,今天学习这个框架,明天研究那个框架,哎,说不出的蛋疼...感觉好累.. ...

  8. 基于WPF系统框架设计(6)-整合MVVM框架(Prism)

    应用场景 我们基础的框架已经搭建起来了,现在整合MVVM框架Prism,在ViewModel做一些逻辑处理,真正把界面设计分离出来. 这样方便我们系统开发分工合作,同时提高系统可维护性和灵活性. 具体 ...

  9. 剖析手写Vue,你也可以手写一个MVVM框架

    剖析手写Vue,你也可以手写一个MVVM框架# 邮箱:563995050@qq.com github: https://github.com/xiaoqiuxiong 作者:肖秋雄(eddy) 温馨提 ...

随机推荐

  1. SpringBoot之普通类获取Spring容器中的bean

    package com.geostar.geostack.git_branch_manager.common; import org.springframework.beans.BeansExcept ...

  2. HTML-Note

    <meta>在 HTML 5 中,有一个新的 charset 属性,它使字符集的定义更加容易. charset character encoding 定义文档的字符编码. e.g. < ...

  3. redis简单命令总结

    1.连接到redis服务器:redis-cli -h 127.0.0.1 -p 6379 -a 密码 select index 切换 redis 数据库 flushdb 删除当前数据库所有的 key ...

  4. [JVM-4]Java内存模型(JMM)

    Java 内存模型 屏蔽掉各种硬件和操作系统的内存访问差异. 1 主内存和工作内存之间的交互 2 对于 volatile 型变量的特殊规则 关键字 volatile 是 Java 虚拟机提供的最轻量级 ...

  5. LFYZ-OJ ID: 1009 阶乘和

    思路 循环n次,每次计算i的阶乘i!,并加入sum中. n的范围从1~100,这里一定要使用高精度运算,涉及到"高精度乘低精度","高精度加高精度". 避免每次 ...

  6. [Android] Android Java String 转Uri

    Uri uri = Uri.parse("https://www.baidu.com") URI uri = new URI("https://www.baidu.com ...

  7. 四十九、进程间通信——System V IPC 之消息队列

    49.1 System V IPC 介绍 49.1.1 System V IPC 概述 UNIX 系统存在信号.管道和命名管道等基本进程间通讯机制 System V 引入了三种高级进程间通信机制 消息 ...

  8. SpringBoot之解决云服务器VPS在所处云端集群的内网不能解析域名的问题:java.net.UnknownHostException:abc.cn: Temporary failure in name resolution

    一.起因与原因分析过程 前端小伙伴儿告诉我,说服务器崩了. 请求数据接口,接口有响应,但报的json提示指向:数据库异常错误. 遂登陆云主机查看日志,核心记录显示如下: 2018-11-09 22:1 ...

  9. django drf 开发 ~ models基础学习

    零 介绍  对于ORM框架,可以简单的认为自定义类U表示数据库的表:根据类创建的对象表示数据库表一 数据表设计  1 类型统计     CharField->(string)->(1 ma ...

  10. C# - LINQ 表达式树

    表达式树(Expression Tree) 表达式树是不可执行的代码,它只是用于表示一种树状的数据结构,树上的每一个节点都表示为某种表达式类型,大概有25种表达式类型,它们都派生自Expression ...