无法在控制器内部访问来自工厂的angularjs数据
我编写了一个从本地websql数据库获取数据的工厂,代码如下:无法在控制器内部访问来自工厂的angularjs数据,angularjs,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.execu
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检查数据是否实际进入工厂。我在控制台中从工厂得到结果,但不是从控制器得到的。请告诉我哪里出了问题。我使用LocalData作为临时变量来存储数组“data”中的数据。这似乎是工厂异步获取数据的问题。在您的控制器中,您正在获取数据,然后立即将其记录下来,但在db.transaction调用完成之前,数据只是一个空列表 即,工厂将立即返回起始listData(即[]),然后在db调用完成后对其进行修改。您的控制器不等待此操作 您需要在控制器中使用$scope.$watch-in用户(除非您将工厂重新编写为使用承诺),以查看它何时更新。如果您只是想在模板中使用它,那么这可能不是必需的。默认情况下,模板可以很好地处理承诺,但是如果您想在javascript中使用它,则需要观察或让工厂使用承诺 因此,用手表:
$scope.$watch('user', function(newVal, oldVal) {
if (newVal !== oldVal) {
console.log('Value changed!', newVal)
}
}
保留现在没有测试它:)实际上,如果异步检索该值,最好返回一个
承诺,而不是监听值更改
此外,工厂应该始终返回一个对象,该对象包含可以在注入后调用的方法,而不是单个函数的结果。这不是工厂的工作方式
我会像这样重写您的代码:
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)
})
})
然后,您可以将其注入某个控制器并检索结果,如下所示:
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)
})
})
编辑:更新代码以解决错误的返回。承诺
我尝试了你的代码,但我遇到了一个错误“无法读取未定义的属性'success'”你能纠正它吗,因为我是angularjs的新手,这个概念对我来说是非常新的东西。你说得对,我错放了延迟的返回。promise
。无论如何,为了你自己的利益,你应该学会调试和解决这类小问题,否则你永远也学不到JavaScriptHere是promises的文档,阅读起来很好(按照角度文档标准,这很容易,不是说很多)。多莫坤就在这里,一个承诺比我建议的手表要好(而且是一件重要的事情)