概述

·  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. 自定义组件的properties和data

    // components/epsoide/index.js Component({ /** * 组件的属性列表 */ properties: { index: { type: Number //va ...

  2. Python——封装

    广义上面向对象的封装:代码的保护,面向对象的思想本身是一种保护,只让自己的对象能调用自己累的方法 狭义上的封装——面向对象的三大特性之一  属性.方法都隐藏起来,不让你看见 规则: 1.所有的私有,都 ...

  3. [BZOJ 2242] [SDOI 2011] 计算器

    Description 你被要求设计一个计算器完成以下三项任务: 给定 \(y,z,p\),计算 \(y^z \bmod p\) 的值: 给定 \(y,z,p\),计算满足 \(xy≡ z \pmod ...

  4. 【AGC015E】Mr.Aoki Incubator DP

    题目描述 数轴上有\(n\)个人,每个人的位置是\(x_i\),速度是\(v_i\). 最开始有一些人感染了传染病. 如果某一时刻一个正常人和一个被感染的人处于同一位置,那么这个正常人也会被感染. 问 ...

  5. Magento 目录基本介绍

    Magento 目录基本介绍 app; 与Magento 1一样,该文件夹包含主要的Magento代码; adminhtml和 frontend;/ app / design / adminhtml和 ...

  6. 【BZOJ5495】[十二省联考2019]异或粽子(主席树,贪心)

    [BZOJ5495][十二省联考2019]异或粽子(主席树,贪心) 题面 BZOJ 洛谷 题解 这不是送分题吗... 转异或前缀和,构建可持久化\(Trie\). 然后拿一个堆维护每次的最大值,每次如 ...

  7. docker基本概念

    详细参考https://www.jianshu.com/p/9deb6f41d5bd

  8. 驱动调试(三)oops确定函数PC

    目录 驱动调试(三)oops确定函数PC 什么是oops 流程简述 代码仓库 模块例子分析 找到PC值 判断是否属于模块 查看符号表 找到模块 反汇编模块 内核例子分析 找到PC值 判断是否属于模块 ...

  9. Centos 7 图形安装笔记(超详细)

    1. 下载虚拟机(VMware Workstation Pro) 2. 安装虚拟机(Windows下安装虚拟机,自行网上搜索) 3. 下载Centos 7.4系统(国内建议使用阿里云: http:// ...

  10. JavaScript事件的属性列表

    HTML 4.0 的新特性之一是能够使 HTML 事件触发浏览器中的行为,比如当用户点击某个 HTML 元素时启动一段 JavaScript.下面是一个属性列表,可将之插入 HTML 标签以定义事件的 ...