前端之MVC应用  

  1、indexedDB(Model): 数据层,前端浏览器 HTML5 API 面向对象数据库,一般现在用的数据库都是关系型数据库。

  那么indexeddb有什么特点呢:

    首先,从字义上它是索引型数据库,从实际使用中可以体现为,它需要为表创建索引才可以根据某个字段来获取数据,而在关系型数据库中,这明显是不需要的。

    其次,我不需要行列数据的转化,我只需要通过类似于数组的处理方式:

  1. objectStore.push(data); // 有点像是把一个json对象塞入数据库,是不是很暴力?

  

  2、bootstrap(View): 

  听说是最近最流行的CSS框架,从3的版本开始往移动端偏移,原来是响应式布局,但比较偏向PC。

  在这里并不使用bootstrap的js插件,因为:我认为它只是一个视图层框架,即使用起来方便,我也还是希望UI组件保持透明,毕竟这样使用起来容易修改。

  3、angularjs(Controller):

  这是一个比较新生代的js框架,和jQuery的意图不同,它希望我们以全局性去考虑一个应用,而非对DOM的操作(这是jQuery做的事情,简化我们操作和访问DOM节点的方式)。

  举个例子:angularjs的使用方式有点像是jsp、freemarker等渲染html的东西,只是一个在客户端渲染,另一个在后台服务器渲染。我们只要改变数据的结构和属性,对应渲染出来的页面就会不同,并且这个过程是自动的。

  如果不太负责地说,可以把angularjs当做是另一种java解释器,它将html混合angularjs自定义指令(或者称为标签)的一个xml文本解析成我们需要的html文本,并且这个过程是动态的,这很符合MVC复合模式中使用到的观察者模式,数据的改变会通知对应绑定的UI组件,告诉它:我的数据变了,希望你能做出对应的变化,让观众能用他们的眼睛看到我的变化,万分感谢!

  同时,用于替代一般的表单验证框架,我们经常会使用到类似于下方的代码

  1. <button ng-disabled="error">save</button>

  上面的代码表示,如果存在错误信息(error是一个变量,布尔型),那么提交按钮将不可用,我们只需要在javascript脚本中对error变量做操作,改变它的值,就可以改变一个流程的走向,是不是有点熟悉感:状态模式。

  总之angularjs可以让我们更加关注数据的变化,而非DOM的变化,就是说:你将很少会去写到

  1. $("#btnSave").click(function() {});

  这样需要获取到html节点的脚本代码,可以说,这完全脱离了jQuery的范畴(当然我们无法否定js的世界有很大一部分都被jQuery占据了)。所以这可以算是一个跨时代的改变?

  码ing(最终必须运行到服务器上),这是一个新增用户的demo,你将会发现:

  1、html页面中发现很多诸多jsp、spring el标签的东西。

  2、数据访问独立成一个模块,加载模块后再通过注入service服务来访问数据库(瞧这,是不是就跟传统的方式不一样了?)

  3、将不会有任何的选择器代码和js绑定事件的方法

  另外:我们使用的资源库均来自互联网,须保持外网畅通,否则将无法正常运行,或者手动将js和css资源替换成本地资源。

user.html:

  1. <!DOCTYPE html>
  2. <html>
  3. <head>
  4. <meta charset="utf-8">
  5. <meta name="viewport" content="width=device-width"/>
  6. <!-- 新 Bootstrap 核心 CSS 文件 -->
  7. <link rel="stylesheet" href="//cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">
  8. <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
  9. </head>
  10. <body ng-app="myApp" ng-controller="userCtrl">
  11. <div class="container">
  12. <h3>Users</h3>
  13. <table class="table table-striped">
  14. <thead>
  15. <tr>
  16. <th>Edit</th>
  17. <th>ID</th>
  18. <th>First Name</th>
  19. <th>Last Name</th>
  20. <th>telephone</th>
  21. </tr>
  22. </thead>
  23. <tbody>
  24. <tr ng-repeat="one in users">
  25. <td>
  26. <button class="btn" ng-click="editUser(one)">
  27. <span class="glyphicon glyphicon-pencil"></span>&nbsp;&nbsp;Edit
  28. </button>
  29. <button class="btn" ng-click="deleteUser(one.id)">
  30. <span class="glyphicon glyphicon-remove"></span>&nbsp;&nbsp;Delete
  31. </button>
  32. </td>
  33. <td>{{ one.id }}</td>
  34. <td>{{ one.fName }}</td>
  35. <td>{{ one.lName }}</td>
  36. <td>{{ one.telephone }}</td>
  37. </tr>
  38. </tbody>
  39. </table>
  40.  
  41. <hr>
  42. <button class="btn btn-success" ng-click="editUser()">
  43. <span class="glyphicon glyphicon-user"></span> Create New User
  44. </button>
  45. <hr>
  46.  
  47. <h3 ng-show="edit">Create New User:</h3>
  48. <h3 ng-hide="edit">Edit User:</h3>
  49.  
  50. <form class="form-horizontal">
  51. <div class="form-group">
  52. <label class="col-sm-2 control-label">First Name:</label>
  53. <div class="col-sm-10">
  54. <input type="text" ng-model="user.fName" ng-disabled="!edit" placeholder="First Name">
  55. </div>
  56. </div>
  57. <div class="form-group">
  58. <label class="col-sm-2 control-label">Last Name:</label>
  59. <div class="col-sm-10">
  60. <input type="text" ng-model="user.lName" ng-disabled="!edit" placeholder="Last Name">
  61. </div>
  62. </div>
  63. <div class="form-group">
  64. <label class="col-sm-2 control-label">telephone:</label>
  65. <div class="col-sm-10">
  66. <input type="tel" ng-model="user.telephone" placeholder="telephone">
  67. </div>
  68. </div>
  69. </form>
  70. <hr>
  71. <button class="btn btn-success" ng-disabled="error || incomplete" ng-click="saveCustomer()">
  72. <span class="glyphicon glyphicon-save"></span> Save Changes
  73. </button>
  74. </div>
  75. <script src="jdbc.js?v=2323"></script>
  76. <script src="myUsers.js"></script>
  77. </body>
  78. </html>

jdbc.js(作为一个数据访问的模块,可供各个应用加载调用)

  1. 'use strict';
  2. !(function (w, angular) {
  3. angular.module('db', []).service('jdbc', function ($http, $q) {
  4. var _self = this;
  5. var myDB = {
  6. name: 'roma',
  7. version: 1,
  8. db: null,
  9. schema: {
  10. 2: function(db) {
  11. // 初始化 用户
  12. var customer = db.createObjectStore('customer', {keyPath:"id", autoIncrement: true});
  13. customer.createIndex("customer_fName_index", "fName", {unique: true});
  14. }
  15. }
  16. };
  17. // 用于处理跟回调函数相反的方式,当defer调用resolve方法之后,就会触发defer.promise.then(callback)传入的callback方法,并且resolve可以传入任意的变量
  18. /**
  19. *
  20. * function test() {
  21. * var defer = $q.defer();
  22. * setTimeout(2000, function() {
  23. * defer.resolve("hello");
  24. * });
  25. * return defer.promise;
  26. * }
  27. *
  28. * test().then(function(say) {
  29. * console.log(say);
  30. * });
  31. *
  32. * 2秒之后将会打印出"hello"
  33. *
  34. * @type {Deferred|*}
  35. */
  36. var defer = $q.defer();
  37. _self.onload = function(cb) {
  38. return defer.promise.then(cb);
  39. };
  40. var getDb = function(db) {
  41. var d = $q.defer();
  42. if (db) {
  43. d.resolve(db);
  44. }
  45. // 打开数据库
  46. var result = window.indexedDB.open(myDB.name);
  47. result.onerror = function (e) {
  48. console.log("Open DB Error!");
  49. d.reject("error");
  50. };
  51. // 正确打开
  52. result.onsuccess = function (e) {
  53. var db = e.target.result;
  54. myDB.db = db;
  55. d.resolve(db);
  56. };
  57. return d.promise;
  58. };
  59. _self.openDB = function (name, version, success, upgrade) {
  60. var d = $q.defer();
  61. var name = name || myDB.name;
  62. var version = version || myDB.version;
  63. // 打开数据库
  64. var result = window.indexedDB.open(name, version);
  65. // 错误
  66. result.onerror = function (e) {
  67. console.log("Open DB Error!");
  68. d.reject(e);
  69. };
  70. // 正确打开
  71. result.onsuccess = function (e) {
  72. myDB.db = e.target.result;
  73. if (success) success(myDB.db);
  74. d.resolve(e);
  75. };
  76. // 数据库版本变更
  77. result.onupgradeneeded = function (e) {
  78. myDB.db = e.target.result;
  79. if (upgrade) upgrade(myDB.db);
  80. d.resolve("upgradeneeded");
  81. };
  82. return d.promise;
  83. };
  84. var schema = function (schema) {
  85. angular.forEach(schema, function(upgrade, version, o) {
  86. _self.openDB(myDB.name, version, function() {
  87. defer.resolve();
  88. }, function(db) {
  89. upgrade(db);
  90. });
  91. })
  92. };
  93. schema(myDB.schema);
  94. _self.get = function (storeName, key) {
  95. var d = $q.defer(); //promise
  96. getDb(myDB.db).then(function (db) {
  97. var transaction = db.transaction(storeName, 'readonly');
  98. var store = transaction.objectStore(storeName);
  99. var result = store.get(key);
  100. result.onsuccess = function (e) {
  101. _self.result = e.target.result;
  102. d.resolve();
  103. };
  104. result.onerror = function (e) {
  105. d.reject();
  106. };
  107. });
  108. return d.promise;
  109. };
  110. _self.find = function (storeName, key, value) {
  111. var d = $q.defer();//promise
  112. getDb(myDB.db).then(function(db) {
  113. var transaction = db.transaction(storeName, 'readonly');
  114. var store = transaction.objectStore(storeName);
  115. var keyRange = IDBKeyRange.only(value);
  116. var result = store.index(key).openCursor(keyRange, "next");
  117. var results = [];
  118. result.onsuccess = function(event) {
  119. var cursor = event.target.result;
  120. if (cursor) {
  121. results.push(cursor.value);
  122. cursor.continue();
  123. } else {
  124. d.resolve(results);
  125. }
  126. };
  127. result.onerror = function (e) {
  128. d.reject();
  129. };
  130. });
  131. return d.promise;
  132. };
  133. _self.put = function (storeName, value) {
  134. var d = $q.defer();
  135. var db = myDB.db || getDb();
  136. var transaction = db.transaction(storeName, 'readwrite');
  137. var store = transaction.objectStore(storeName);
  138. if (value !== null && value !== undefined) {
  139. store.put(value);
  140. d.resolve();
  141. } else {
  142. d.reject();
  143. }
  144. return d.promise;
  145. };
  146. _self.remove = function (storeName, value) {
  147. var d = $q.defer();//promise
  148. var db = myDB.db || getDb();
  149. var transaction = db.transaction(storeName, 'readwrite');
  150. var store = transaction.objectStore(storeName);
  151. var result = store.delete(value);
  152. result.onsuccess = function (e) {
  153. d.resolve();
  154. };
  155. result.onerror = function (e) {
  156. d.reject();
  157. };
  158. return d.promise;
  159. };
  160. _self.findAll = function (storeName) {
  161. var d = $q.defer();//promise
  162. getDb(myDB.db).then(function(db) {
  163. var transaction = db.transaction(storeName, 'readonly');
  164. var store = transaction.objectStore(storeName);
  165. var result = store.openCursor();
  166. var results = [];
  167. result.onsuccess = function (event) {
  168. var cursor = event.target.result;
  169. if (cursor) {
  170. results.push(cursor.value);
  171. cursor.continue();
  172. } else {
  173. d.resolve(results);
  174. }
  175. };
  176. result.onerror = function (e) {
  177. d.reject();
  178. };
  179. });
  180. return d.promise;
  181. };
  182. return _self;
  183. });
  184. }(window, window.angular));

myUsers.js (应用的controller层脚本):

  1. 'use strict';
  2. angular.module('myApp', ['db']).controller("userCtrl", function($scope, $http, jdbc) {
  3. // 刷新数据结构,angularjs的双向绑定会自动帮我们渲染界面
  4. function reload() {
  5. jdbc.findAll("customer").then(function(response) {
  6. if (!response) {
  7. $http.get("data.json").success(function(response) {
  8. $scope.users = response;
  9. });
  10. return;
  11. }
  12. $scope.users = response;
  13. });
  14. }
  15. // 数据结构完成之后刷新界面
  16. jdbc.onload(reload);
  17. $scope.edit = true;
  18. var _user = $scope.user = {};
  19. $scope.editUser = function(user) {
  20. if (user) {
  21. _user.id = user.id;
  22. _user.fName = user.fName;
  23. _user.lName = user.lName;
  24. _user.telephone = user.telephone;
  25. } else {
  26. $scope.user = _user = {};
  27. }
  28. };
  29. $scope.deleteUser = function(id) {
  30. // 从数据库删除记录之后刷新表格数据
  31. jdbc.remove("customer", id).then(reload);
  32. };
  33. $scope.saveCustomer = function() {
  34. // 从数据库添加或更新记录之后刷新表格数据
  35. jdbc.put("customer", _user).then(reload);
  36. };
  37. jdbc.find("customer", "customer_fName_index", "林").then(function(data) {
  38. console.log(data);
  39. });
  40. });

data.json(当indexedDB无法正常获取的时候用来显示数据用)

  1. [
  2. {
  3. "id": 1,
  4. "fName": "林",
  5. "lName": "嘉斌",
  6. "telephone": "13514087953"
  7. },
  8. {
  9. "id": 2,
  10. "fName": "陈",
  11. "lName": "晓",
  12. "telephone": "13509890786"
  13. }
  14. ]

              

indexedDB bootstrap angularjs 前端 MVC Demo的更多相关文章

  1. AngularJS 前端 MVC 的设计与搭建

    代码 #未引入MVC框架之前的代码 <!doctype html> <html> <head> <meta charset="UTF-8" ...

  2. 前端MVC学习总结——AngularJS验证、过滤器

    前端MVC学习总结--AngularJS验证.过滤器 目录 一.验证 二.过滤器 2.1.内置过滤器 2.1.1.在模板中使用过滤器 2.1.2.在脚本中调用过滤函数 2.2.自定义过滤器 三.指令( ...

  3. bootstrap + angularjs + seajs构建Web Form前端2

    bootstrap + angularjs + seajs构建Web Form前端(二) 回顾 上一篇讲解了引入bootstrap构建一个简单的登录页面,如何让angularjs自动启动并绑定视图,操 ...

  4. bootstrap + angularjs + seajs构建Web Form前端(1)

    bootstrap + angularjs + seajs构建Web Form前端(一) 简介 Bootstrap是Twitter推出的一个用于前端开发的开源工具包,它由Twitter的设计师Mark ...

  5. 前端开发利器: Bootstrap + AngularJS

    http://blog.csdn.net/conquer0715/article/details/51181391 概述 在HTML5盛行的互联网时代,涌现诸多的前端html/css/js框架,基于其 ...

  6. 前端MVC框架、类库、UI框架选择

    CSS预处理器sass(基于Ruby服务端版)less(客户端版:基于js; 服务端版:基于nodejs) 前端UI框架JqueryMiniUI: http://www.miniui.com/(适用于 ...

  7. Angularjs,WebAPI 搭建一个简易权限管理系统 —— Angularjs 前端主体结构(五)

    目录 前言 Angularjs名词与概念 Angularjs 基本功能演示 系统业务与实现 WebAPI项目主体结构 Angularjs 前端主体结构 6 Angularjs 前端主体结构 6.1 A ...

  8. 前端MVC学习总结(一)——MVC概要与angular概要、模板与数据绑定

    一.前端MVC概要 1.1.库与框架的区别 框架是一个软件的半成品,在全局范围内给了大的约束.库是工具,在单点上给我们提供功能.框架是依赖库的.AngularJS是框架而jQuery则是库. 1.2. ...

  9. 完成AngularJS with MVC 5, Web API 2项目

    经过接近两个月的日夜奋战,完成AngularJS with MVC 5, Web API 2的项目,这也是进入公司以后最大的一个项目,从项目需求.用户Prototype/Demo,招人,开发完成,可谓 ...

随机推荐

  1. Android Wear开发 - 数据通讯 - 第三节 : 事件处理

    http://developer.android.com/training/wearables/data-layer/events.html 以下是本人在学习官方开发文档时的笔记,主要是翻译为主,并在 ...

  2. 老毛桃U盘启动盘制作工具V20140501完美贡献版

    老毛桃U盘启动盘制作工具V20140501完美贡献版 下载地址:http://down.laomaotao.net:90/LaoMaoTao_V2014zhuangji.exe 老毛桃U盘装系统综合教 ...

  3. Strange Way to Express Integers (一般模线性方程组)

    Time Limit: 1000MS   Memory Limit: 131072K Total Submissions: 8476   Accepted: 2554 Description Elin ...

  4. A Knight's Journey(dfs)

    Time Limit: 1000MS   Memory Limit: 65536K Total Submissions: 25950   Accepted: 8853 Description Back ...

  5. Linux企业级开发技术(4)——epoll企业级开发之epoll例程

    为了使大家更加深入了解epoll模型在企业应用中的使用,下面给出一段基于epoll的服务器代码,并在代码中添加了详细注释: #include <deque> #include <ma ...

  6. POJ 3436 ACM Computer Factory

    题意:   为了追求ACM比赛的公平性,所有用作ACM比赛的电脑性能是一样的,而ACM董事会专门有一条生产线来生产这样的电脑,随着比赛规模的越来越大,生产线的生产能力不能满足需要,所以说ACM董事会想 ...

  7. Python操作Excel_输出所有内容(包含中文)

    python 2.7.5代码: # coding=utf-8 import sys import xlrd data=xlrd.open_workbook('D:\\menu.xls') table ...

  8. Nodejs in Visual Studio Code 14.IISNode与IIS7.x

    1.开始 部署IISNode环境请参考:Nodejs in Visual Studio Code 08.IIS 部署Nodejs程序请参考:Nodejs in Visual Studio Code 1 ...

  9. Break、continue、return用法(C++)

    (1)break 直接调出当前循环体.如果是嵌套循环,他只能调出一层循环体. Exp-1: 程序: #include<iostream> using namespace std; int ...

  10. POJ 2912 Rochambeau

    题意:有一些人玩石头剪刀布,其中有一个人(称其为裁判)可以出“石头”,“剪刀”,“布”中的任意一个,其他人永远只能出相同的一个.即有的人只能出剪刀,有的人只能出石头,有的人只能出布.进行了多次对决,每 ...