来自工厂的angularjs-data无法在控制器内部访问

时间:2014-07-09 09:12:54

标签: angularjs

我已经编写了一个从本地websql数据库获取数据的工厂。代码如下:

app.factory('readData', function () {
var localData=[];
var data=[];
var db = openDatabase("here is ma database");
var selectAllStatement = "SELECT * FROM tablename"; 

  db.transaction(function (tx) {
        tx.executeSql(selectAllStatement, [], function (tx, result) {
             dataset = result.rows;
            for (var i = dataset.length - 1; i >= 0; i--) {
             data[i]=dataset.item(i);

            }; 
              localData=data;

            console.log(data);  
            return localData; 

        });

    });
return localData ;});

此工厂用于控制器以获取数据。代码为:

function tricoreContrller($scope, readData) {$scope.users = readData;console.log( $scope.users);}tricoreContrller($scope, readData);

我已经使用console.log来检查数据是否实际进入工厂。我从工厂得到了控制台的结果而不是来自controller.Plz tel me我在哪里出错。我使用LocalData作为存储的temprary变量来自数组“data”的数据。

2 个答案:

答案 0 :(得分:1)

这看起来是工厂异步获取数据的问题。在您的控制器中,您将获取数据,然后立即将其记录下来,但在db.transaction调用完成之前,数据只是一个空列表。

即。工厂将立即返回起始listData(即[]),然后在db-call完成后修改它。你的控制器不会等待这个。

您将需要在控制器中的用户中使用$ scope。$ watch(除非您重新编写工厂以使用promises),以查看它何时更新。如果您只想在模板中使用它,则可能没有必要,默认情况下模板处理承诺很好,但如果您想在javascript中使用它,您需要观察或让工厂使用承诺。

所以用手表:

$scope.$watch('user', function(newVal, oldVal) {
    if (newVal !== oldVal) {
        console.log('Value changed!', newVal)
    } 
}

预约未立即测试:)

答案 1 :(得分:1)

实际上,如果以异步方式检索值,则最好返回promise,而不是监听值更改。

此外,工厂应始终返回一个对象,该对象具有可在注入后调用的方法,而不是单个函数的结果。这不是factory应该如何工作的。

我会像这样重写你的代码:

app.factory('readData', function ($q) {

  var localData=[];
  var data=[];
  var db = openDatabase("here is ma database");
  var selectAllStatement = "SELECT * FROM tablename";

  // here starts your public API, that is the method you can invoke
  return {
    transaction: function () {

      // initialize a deferred method
      var deferred = $q.defer()

      db.transaction(function (tx) {
        tx.executeSql(selectAllStatement, [], function (tx, result) {
          // you forgot about 'var' here
          var dataset = result.rows;

          for (var i = dataset.length - 1; i >= 0; i--) {
            data[i]=dataset.item(i);
          }

          // set your data as the successful result of your promise
          deferred.resolve(data)

        })
      })

      // return the promise (that is, the async data)
      return deferred.promise
    }
  }

})

然后你可以将它注入某个控制器并检索结果如下:

app.controller('myCtrl', function (readData) {

  readData.transaction()
    .success(function (data) {
      console.log(data)
    })
})

修改更新的代码,以解决放错位置的return.promise