我正在开发一个 Angular 应用程序。我需要在 SQLite 中创建一个数据库,以便在我的 Android 项目中本地使用。我看到的每个教程都教我在工厂中制作它并在其他页面中调用它。
问题是,在很多情况下,我需要获取这些信息并对其进行操作。我已经能够在表单中显示它,但不幸的是,我无法操作从工厂返回的对象。
我的代码如下。
工厂 sqlite:
var db = null;
var clienteselec = [];
var sqlite = angular.module('sqlite', ['ionic', 'ngCordova']);
sqlite.run(function ($ionicPlatform, $cordovaSQLite, $window) {
$ionicPlatform.ready(function () {
db = $cordovaSQLite.openDB({ name: "rollers.db", location: 1 });
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS clientes (id integer primary key, nome varchar(40))");
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS instalacao (id integer primary key, idCliente int, dataInst datetime)");
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS manutencao (id integer primary key, idCliente int, idInstalacao int, dataManut datetime)");
$cordovaSQLite.execute(db, "CREATE TABLE IF NOT EXISTS equipamento (id integer primary key, idInstalacao int, idManutencao int, TC int autoincrement, posicao varcar(1), Rolo varchar(40), dataEquip datetime)");
});
})
sqlite.factory('clientesFactory', function ($cordovaSQLite, $rootScope) {
return {
insert: function (Nome) {
var query = "INSERT INTO clientes (nome) VALUES (?);";
var values = [Nome];
$cordovaSQLite.execute(db, query, values).then(
function (res) {
alert('Cliente Cadastro com Sucesso!');
$cordovaSQLite.execute(db, "SELECT max(id) as id from clientes", []).then(
function (res) {
if (res.rows.length > 0) {
var valores = res.rows.item(0);
$rootScope.idCliente = valores.id;
}
}
);
},
function (err) {
alert('Cliente não cadastrado. Estamos verificando o problema!');
}
);
},
selectTodos: function(tab){
var query = "SELECT * FROM " + tab;
clienteselec = [];
$cordovaSQLite.execute(db, query,[]).then(function (result) {
if(result.rows.length){
for (var i = 0; i < result.rows.length; i++) {
clienteselec.push(result.rows.item(i));
}
}else{
console.log("no data found!");
}
}, function(err){
console.log("error" + err);
});
},
});
Controller :
.controller('ClienteCtrl', ['clientesFactory', '$scope', '$state', '$window', '$rootScope', function (clientesFactory, $scope, $state, $window, $rootScope) {
$scope.listaClientes = function() {
clientesFactory.insert('teste');
clientesFactory.selectTodos('clientes');
$scope.seleciona = clienteselec;
}
}])
HTML:
<ion-content padding>
<div ng-controller="ClienteCtrl">
<button ng-click="listaClientes()">Novo Cliente</button>
<!--<table>
<tr ng-repeat="cli in clientes">
<td></td>
</tr>
</table>-->
<ion-item ng-repeat="cli in seleciona">
{{cli.nome}}
<button ng-click="cadastraCliente({{cli.id}})">Novo</button>
<button ng-click="instala({{cli.id}}, {{cli.nome}})">Instalação</button>
<button ng-click="excluiCliente({{cli.id}}, {{cli.nome}})">Excluir</button>
</div>
</ion-content>
有人能帮忙吗?
最佳答案
您的代码存在很多架构问题,但在您开始新事物时这很正常。 :)
我正在考虑使用数据库的基础工作(我没有测试),通过全局变量将数据传递给 Controller 的整体方法是错误的,请不惜一切代价避免这种情况/javascript 世界。
你需要考虑更多让我们说模块化或面向对象并尝试封装它。如果不这样做,您的代码将非常脆弱并且容易出错,因为即使您的脚本顺序也可能破坏它。
我对你的代码做了一些调整,见下文:
工厂:
angular.module('sqlite', ['ionic', 'ngCordova'])
.run(function ($ionicPlatform, $cordovaSQLite) {
$ionicPlatform.ready(function () {
var db = $cordovaSQLite.openDB({ name: 'rollers.db', location: 1 });
$cordovaSQLite.execute(db, 'CREATE TABLE IF NOT EXISTS clientes (id integer primary key, nome varchar(40))');
$cordovaSQLite.execute(db, 'CREATE TABLE IF NOT EXISTS instalacao (id integer primary key, idCliente int, dataInst datetime)');
$cordovaSQLite.execute(db, 'CREATE TABLE IF NOT EXISTS manutencao (id integer primary key, idCliente int, idInstalacao int, dataManut datetime)');
$cordovaSQLite.execute(db, 'CREATE TABLE IF NOT EXISTS equipamento (id integer primary key, idInstalacao int, idManutencao int, TC int autoincrement, posicao varcar(1), Rolo varchar(40), dataEquip datetime)');
});
})
//I will not recommend you to use rootScope like that.
//I added $q to work with the $cordovaSQLite promises
.factory('clientesFactory', function ($cordovaSQLite, $q /*$rootScope*/) {
//local variables, no needs to be global
var db = $cordovaSQLite.openDB({ name: 'rollers.db', location: 1 });
//better approach for legibility
return {
insert: insert,
selectTodos: selectTodos
};
function insert(Nome) {
var query = 'INSERT INTO clientes (nome) VALUES (?);';
var values = [Nome];
//since this is a assynchronous method
//we can return this promise and let the caller lead with it
return $cordovaSQLite.execute(db, query, values)
.then(function () {
var deferred = $q.defer();
// returns the data in the promise sucess
deferred.resolve('Cliente Cadastro com Sucesso!');
/*
//This is really necessary?
//If so, why not to convert it in another method?
$cordovaSQLite.execute(db, 'SELECT max(id) as id from clientes', []).then(
function (res) {
if (res.rows.length > 0) {
var valores = res.rows.item(0);
$rootScope.idCliente = valores.id;
}
}
);*/
})
.catch(function () { //promises have a catch method to capture the error
//returns the data with error
deferred.reject('Cliente não cadastrado. Estamos verificando o problema!');
});
}
function selectTodos(tab) {
var query = 'SELECT * FROM ' + tab;
//since this is a assynchronous method
//we can return this promise and let the caller lead with it
return $cordovaSQLite.execute(db, query, [])
.then(function (result) {
var deferred = $q.defer();
if (!result.rows.length) {
//returns the data with error
deferred.reject('No data found!');
}
var clienteselec = [];
for (var i = 0; i < result.rows.length; i++) {
clienteselec.push(result.rows.item(i));
}
//returns the data in the promise sucess
deferred.resolve(clienteselec);
})
.catch(function (err) { //promises have a catch method to capture the error
console.log('error' + err);
});
}
})
Controller :
.controller('ClienteCtrl', ['clientesFactory', '$scope', '$state', '$window', '$rootScope', function (clientesFactory, $scope, $state, $window, $rootScope) {
$scope.listaClientes = listaClientes;
$scope.seleciona = [];
function listaClientes() {
//Now, let the promise magic happens
//and lead with it here in the controller logic
clientesFactory.insert('teste')
.then(function (response) {
console.log(response);
})
.catch(function (err) {
//use console.error to show erros :)
console.error(err);
});
clientesFactory.selectTodos('clientes')
.then(function (response) {
$scope.clienteselec = response;
})
.catch(function (err) {
//use console.error to show erros :)
console.error(err);
});
}
}]);
希望 View 不会发生任何变化:
<ion-content padding>
<div ng-controller="ClienteCtrl">
<button ng-click="listaClientes()">Novo Cliente</button>
<ion-item ng-repeat="cli in seleciona">
{{ cli.nome }}
<button ng-click="cadastraCliente({{cli.id}})">Novo</button>
<button ng-click="instala({{cli.id}}, {{cli.nome}})">Instalação</button>
<button ng-click="excluiCliente({{cli.id}}, {{cli.nome}})">Excluir</button>
</div>
免责声明:我不会在任何地方运行这段代码,所以我很确定这不会像现在这样工作。您将需要进行必要的调整,希望这将为您提供如何将数据从服务(工厂)传递到 Controller 的总体方法,以及一些良好的编程实践。如果您想了解更多有关如何以正确的方式制作 Angular 应用程序的信息,我强烈建议您查看 John Papa 的 Angular 风格指南:https://github.com/johnpapa/angular-styleguide .
干杯,
关于android - 无法在 Controller 中操作工厂信息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43380446/