改进AngularJS Simple Factory - 围绕PhoneGap Storage API的包装

时间:2013-10-17 07:18:58

标签: javascript angularjs cordova

我正在尝试用我一般的JS技能在AngularJS中做一些“好”的事情,我想听听你对你的感受或改进/重构如何:

angular.module('App').factory("SQLService", function ($q) {

    var db = window.openDatabase("FOOD_DATABASE", app.current_version, "FOOD_DATABASE_DN", 5 * 1024 * 1024);

    // public methods
    function getCategories(){
      deferred = $q.defer();

      db.transaction(queryDB, errorCB);

      function queryDB(tx) {
        tx.executeSql('SELECT * FROM CATEGORIES', [], querySelectSuccess, errorCB);
      }

      return deferred.promise;
    }

    function getDishes(){
      deferred = $q.defer();

      db.transaction(queryDB, errorCB);

      function queryDB(tx) {
        tx.executeSql('SELECT * FROM DISHES', [], querySelectSuccess, errorCB);
      }

      return deferred.promise;
    }

    // something like private methods
    function errorCB(err) {
      alert("Error processing SQL: " + err.code);
    }

    function querySelectSuccess(tx, results) {
      var len = results.rows.length;
      var output_results = [];

      for (var i=0; i<len; i++){
        output_results.push(results.rows.item(i));
      }

      deferred.resolve(output_results);

    }

  //expose object with public methods
  return {
    getCategories: getCategories,
    getDishes: getDishes,

  };

});

我不喜欢的第一件事是在每个公共函数中创建全局deferred = $q.defer();,如果我将其声明为本地,那么我不知道如何将该deffered对象作为额外参数传递给querySelectSuccess回调。或者我应该以某种方式更好地重构一切?你的意见是什么?

2 个答案:

答案 0 :(得分:2)

http://rburns.paiges.net/about/以下是:

function getCategories(){
  return promisedQuery('SELECT * FROM CATEGORIES', defaultResultHandler, defaultErrorHandler);
}

function getDishes(){
  return promisedQuery('SELECT * FROM DISHES', defaultResultHandler, defaultErrorHandler);
}

function defaultResultHandler(deferred) {
  return function(tx, results) {
    var len = results.rows.length;
    var output_results = [];

    for (var i=0; i<len; i++){
      output_results.push(results.rows.item(i));
    }

    deferred.resolve(output_results);  
  }  
}

function defaultErrorHandler(err) {
  alert("Error processing SQL: " + err.code);
}

function promisedQuery(query, successCB, errorCB) {
  var deferred = $q.defer();
  db.transaction(function(tx){
    tx.executeSql(query, [], successCB(deferred), errorCB);      
  }, errorCB);
  return deferred.promise;  
}

答案 1 :(得分:0)

也许我错了,但是从我的第一次有角度的exp我觉得有些东西你错过了我错过了它

如果你将视图(UI)strait连接到服务/工厂,那么你不需要deffered和所有类型的更新,但它会自动更新它,并像这样完成

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
    <style>
        .main { width: 400px; }
        .singleItem { width: 25%; display:inline-block; border: 2px dashed green; }
        .textContainer { text-align: center; }
    </style>
    <script src="angular.js"></script>
    <script >
        var myStudyModule = angular.module('myStudyModule', []);

        myStudyModule.service('myService', function ($http) {
            console.log("myService");
            var self = this;
            self.catalog = [];

            self.getData = function (parentKey, level) {
                console.log("myService.getMyData");
                var url = 'Handler1.ashx';
                if (parentKey && level)
                    url += '?parentKey=' + parentKey + '&level=' + level;
                $http.get(url).success(function (data) {
                    console.log("$http.get.success");
                    self.catalog = data;
                });
            };

            self.getData();
        });

        var myController = function ($scope, myService) {
            console.log("myController");
            $scope.myService = myService;

            $scope.MainItemClick = function (catalogItem) {
                console.log("$scope.MainItemClick");
                myService.getData(catalogItem.key, catalogItem.level + 1);
            };
        };

        myStudyModule.controller(myController);
    </script>
</head>
<body>
    <div class="main" ng-app="myStudyModule" ng-controller="myController"> 
        <div class="singleItem" ng-repeat="catalogItem in myService.catalog" ng-click="MainItemClick(catalogItem)" >
            <a class="box" href="#" >
                <img ng-src="{{ catalogItem.image }}" width="100">
                <div class="textContainer" >
                    <h4>{{ catalogItem.level }} - {{ catalogItem.name }}</h4>
                </div>
            </a>
        </div>
    </div>
</body>
</html>

顺便说一句,我在这里有更多的自学案例 https://skydrive.live.com/redir?resid=949DC4EDBFFD4738!227&authkey=!AO_dsCMOFqndeLU