你的位置:首页 > Java教程

[Java教程]indexedDB bootstrap angularjs之 MVC Demo


前端之MVC应用  

  1、indexedDB(Model) -- 前端浏览器对象型数据库,一般我们后台用的数据库都是关系型数据库。那么indexeddb有什么特点呢:

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

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

objectStore.push(data);

  有点像是把一个json对象塞入数据库,是不是很暴力?

 

  2、bootstrap(View)  -- bootstrap,老实说,我不是很熟悉这个东西,毕竟我是后端java开发出身。以我的理解,这就是一个以响应式布局为特点的前端框架,至于说比较特别的,应该就是它比较流行吧?!老实说,我这边只用到css,而我也认为,后现代的前端开发,将不会需要bootstrap的js部分,毕竟那还是以jquery为主的方式。

 

  3、angularjs(Controller)  -- 必须承认这个东西东西的诞生完全颠覆了我对前端开发的看法,以前和现在我们依然困在前后端无法彻底分离的窘境中,但我认为如果后期,前端人员普遍采用应用式的angularjs脚本来开发(还有一些类似的框架),我们将不再需要让后端开发工程师套用诸多的前端样式、结构等等。

  这么说,很多后端人员可能还是不能体会得到,举个例子:angularjs的使用方式有点像是jsp、freemarker等渲染html的东西,只是一个在客户端渲染,另一个在后台服务器渲染。我们只要改变数据的结构和属性,对应渲染出来的页面就会不同,angularjs就是让我们更加关注数据的变化,而非DOM的变化,就是说:你将很少会去写到$("btnSave").click(function() {});这样需要获取到html节点的脚本代码,可以说,这完全脱离了jQuery的范畴。所以这可以算是一个跨时代的改变?

 

  接下来就上例子吧(最终必须运行到服务器上):

user.html

<!DOCTYPE html><html><head>  <meta charset="utf-8">  <meta name="viewport" content="width=device-width"/>  <!-- 新 Bootstrap 核心 CSS 文件 -->  <link rel="stylesheet" href="http://www.cnblogs.com///cdn.bootcss.com/bootstrap/3.3.5/css/bootstrap.min.css">  <script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script></head><body ng-app="myApp" ng-controller="userCtrl"><div class="container">  <h3>Users</h3>  <table class="table table-striped">    <thead>    <tr>      <th>Edit</th>      <th>First Name</th>      <th>Last Name</th>    </tr>    </thead>    <tbody>    <tr ng-repeat="one in users">      <td>        <button class="btn" ng-click="editUser(one)">          <span class="glyphicon glyphicon-pencil"></span>&nbsp;&nbsp;Edit        </button>        <button class="btn" ng-click="deleteUser(one.id)">          <span class="glyphicon glyphicon-remove"></span>&nbsp;&nbsp;Delete        </button>      </td>      <td>{{ one.fName }}</td>      <td>{{ one.lName }}</td>      <td>{{ one.telephone }}</td>    </tr>    </tbody>  </table>  <hr>  <button class="btn btn-success" ng-click="editUser()">    <span class="glyphicon glyphicon-user"></span> Create New User  </button>  <hr>  <h3 ng-show="edit">Create New User:</h3>  <h3 ng-hide="edit">Edit User:</h3>  <form class="form-horizontal">    <div class="form-group">      <label class="col-sm-2 control-label">First Name:</label>      <div class="col-sm-10">        <input type="text" ng-model="user.fName" ng-disabled="!edit" placeholder="First Name">      </div>    </div>    <div class="form-group">      <label class="col-sm-2 control-label">Last Name:</label>      <div class="col-sm-10">        <input type="text" ng-model="user.lName" ng-disabled="!edit" placeholder="Last Name">      </div>    </div>    <div class="form-group">      <label class="col-sm-2 control-label">telephone:</label>      <div class="col-sm-10">        <input type="tel" ng-model="user.telephone" placeholder="telephone">      </div>    </div>  </form>  <hr>  <button class="btn btn-success" ng-click="saveCustomer()">    <span class="glyphicon glyphicon-save"></span> Save Changes  </button></div><script src="jdbc.js?v=2323"></script><script src="myUsers.js"></script></body></html>

 

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

'use strict';!(function (w, angular) {  angular.module('db', []).service('jdbc', function ($http, $q) {    var _self = this;    var myDB = {      name: 'roma',      version: 1,      db: null,      schema: {        2: function(db) {          // 初始化 用户          var customer = db.createObjectStore('customer', {keyPath:"id", autoIncrement: true});          customer.createIndex("customer_fName_index", "fName", {unique: true});        }      }    };    // 用于处理跟回调函数相反的方式,当defer调用resolve方法之后,就会触发defer.promise.then(callback)传入的callback方法,并且resolve可以传入任意的变量    /**     *     * function test() {     * var defer = $q.defer();     * setTimeout(2000, function() {     *   defer.resolve("hello");     * });     * return defer.promise;     * }     *     * test().then(function(say) {     * console.log(say);     * });     *     * 2秒之后将会打印出"hello"     *     * @type {Deferred|*}     */    var defer = $q.defer();    _self.onload = function(cb) {      return defer.promise.then(cb);    };    var getDb = function(db) {      var d = $q.defer();      if (db) {        d.resolve(db);      }      // 打开数据库      var result = window.indexedDB.open(myDB.name);      result.onerror = function (e) {        console.log("Open DB Error!");        d.reject("error");      };      // 正确打开      result.onsuccess = function (e) {        var db = e.target.result;        myDB.db = db;        d.resolve(db);      };      return d.promise;    };    _self.openDB = function (name, version, success, upgrade) {      var d = $q.defer();      var name = name || myDB.name;      var version = version || myDB.version;      // 打开数据库      var result = window.indexedDB.open(name, version);      // 错误      result.onerror = function (e) {        console.log("Open DB Error!");        d.reject(e);      };      // 正确打开      result.onsuccess = function (e) {        myDB.db = e.target.result;        if (success) success(myDB.db);        d.resolve(e);      };      // 数据库版本变更      result.onupgradeneeded = function (e) {        myDB.db = e.target.result;        if (upgrade) upgrade(myDB.db);        d.resolve("upgradeneeded");      };      return d.promise;    };    var schema = function (schema) {      angular.forEach(schema, function(upgrade, version, o) {        _self.openDB(myDB.name, version, function() {          defer.resolve();        }, function(db) {          upgrade(db);        });      })    };    schema(myDB.schema);    _self.get = function (storeName, key) {      var d = $q.defer(); //promise      getDb(myDB.db).then(function (db) {        var transaction = db.transaction(storeName, 'readonly');        var store = transaction.objectStore(storeName);        var result = store.get(key);        result.onsuccess = function (e) {          _self.result = e.target.result;          d.resolve();        };        result.onerror = function (e) {          d.reject();        };      });      return d.promise;    };    _self.find = function (storeName, key, value) {      var d = $q.defer();//promise      getDb(myDB.db).then(function(db) {        var transaction = db.transaction(storeName, 'readonly');        var store = transaction.objectStore(storeName);        var keyRange = IDBKeyRange.only(value);        var result = store.index(key).openCursor(keyRange, "next");        var results = [];        result.onsuccess = function(event) {          var cursor = event.target.result;          if (cursor) {            results.push(cursor.value);            cursor.continue();          } else {            d.resolve(results);          }        };        result.onerror = function (e) {          d.reject();        };      });      return d.promise;    };    _self.put = function (storeName, value) {      var d = $q.defer();      var db = myDB.db || getDb();      var transaction = db.transaction(storeName, 'readwrite');      var store = transaction.objectStore(storeName);      if (value !== null && value !== undefined) {        store.put(value);        d.resolve();      } else {        d.reject();      }      return d.promise;    };    _self.remove = function (storeName, value) {      var d = $q.defer();//promise      var db = myDB.db || getDb();      var transaction = db.transaction(storeName, 'readwrite');      var store = transaction.objectStore(storeName);      var result = store.delete(value);      result.onsuccess = function (e) {        d.resolve();      };      result.onerror = function (e) {        d.reject();      };      return d.promise;    };    _self.findAll = function (storeName) {      var d = $q.defer();//promise      getDb(myDB.db).then(function(db) {        var transaction = db.transaction(storeName, 'readonly');        var store = transaction.objectStore(storeName);        var result = store.openCursor();        var results = [];        result.onsuccess = function (event) {          var cursor = event.target.result;          if (cursor) {            results.push(cursor.value);            cursor.continue();          } else {            d.resolve(results);          }        };        result.onerror = function (e) {          d.reject();        };      });      return d.promise;    };    return _self;  });}(window, window.angular));

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

'use strict';angular.module('myApp', ['db']).controller("userCtrl", function($scope, $http, jdbc) {  // 刷新数据结构,angularjs的双向绑定会自动帮我们渲染界面  function reload() {    jdbc.findAll("customer").then(function(response) {      if (!response) {        $http.get("data.json").success(function(response) {          $scope.users = response;        });        return;      }      $scope.users = response;    });  }  // 数据结构完成之后刷新界面  jdbc.onload(reload);  $scope.edit = true;  var _user = $scope.user = {};  $scope.editUser = function(user) {    if (user) {      _user.id = user.id;      _user.fName = user.fName;      _user.lName = user.lName;      _user.telephone = user.telephone;    } else {      _user.fName = "";      _user.lName = "";      _user.telephone = "";      _user.id = "";    }  };  $scope.deleteUser = function(id) {    // 从数据库删除记录之后刷新表格数据    jdbc.remove("customer", id).then(reload);  };  $scope.saveCustomer = function() {    // 从数据库添加或更新记录之后刷新表格数据    jdbc.put("customer", _user).then(reload);  };  jdbc.find("customer", "customer_fName_index", "林").then(function(data) {    console.log(data);  });});

 

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

[ {  "id": 1,  "fName": "林",  "lName": "嘉斌",  "telephone": "13514087953" }, {  "id": 2,  "fName": "陈",  "lName": "晓",  "telephone": "13509890786" }]