草庐IT

mysql - 有没有办法可以在 Ionic 2 中同步 MySQL 服务器和 SQlite?

coder 2023-10-26 原文

我想将 MySQL 服务器数据库同步到 ionic 2 中的本地 sqlite 数据库,以使用户能够离线存储信息,然后在在线时调用/发送更改。

我已经看到了一些让它在 android 中工作的方法,但我没有在 ionic 2 中找到太多关于它的信息。

最佳答案

我们假设您已经安装了 Node.js 并且能够在 Node.js 命令行 (Windows) 或终端 (OS X/Linux) 中运行 npm。为确保一切都是最新的,请在终端或 Node 命令行中键入此命令。

npm install -g ionic cordova

要添加 Ionic 3 Native SQLite 和 Toast 插件,只需键入此命令。

ionic cordova plugin add cordova-sqlite-storage
npm install --save @ionic-native/sqlite
ionic cordova plugin add cordova-plugin-x-toast
npm install --save @ionic-native/toast

现在,打开并编辑 src/app/app.module.ts 然后添加这个导入。

import { SQLite } from '@ionic-native/sqlite';
import { Toast } from '@ionic-native/toast';

SQLiteToast 添加到 @NgModule 提供程序,所以它看起来像这样。

providers: [
  StatusBar,
  SplashScreen,
  {provide: ErrorHandler, useClass: IonicErrorHandler},
  SQLite,
  Toast
]

使用 Ionic 3、Angular 4 和 SQLite 实现 CRUD 移动应用程序首先要创建费用 list 。为此,打开并编辑默认 src/pages/home/home.ts 然后添加此导入。

import { SQLite, SQLiteObject } from '@ionic-native/sqlite';
import { AddDataPage } from '../add-data/add-data';
import { EditDataPage } from '../edit-data/edit-data';

添加和编辑数据的两次导入需要新页面来添加和编辑稍后将添加的数据。现在,在构造函数变量上注入(inject) SQLite

constructor(public navCtrl: NavController,
  private sqlite: SQLite) {}

在构造函数之前为费用数组、总收入、总费用和余额添加此变量。

expenses: any = [];
totalIncome = 0;
totalExpense = 0;
balance = 0;

将此函数添加到完整 CRUD 的构造函数下方。

ionViewDidLoad() {
  this.getData();
}

ionViewWillEnter() {
  this.getData();
}

getData() {
  this.sqlite.create({
    name: 'ionicdb.db',
    location: 'default'
  }).then((db: SQLiteObject) => {
    db.executeSql('CREATE TABLE IF NOT EXISTS expense(rowid INTEGER PRIMARY KEY, date TEXT, type TEXT, description TEXT, amount INT)', {})
    .then(res => console.log('Executed SQL'))
    .catch(e => console.log(e));
    db.executeSql('SELECT * FROM expense ORDER BY rowid DESC', {})
    .then(res => {
      this.expenses = [];
      for(var i=0; i<res.rows.length; i++) {
        this.expenses.push({rowid:res.rows.item(i).rowid,date:res.rows.item(i).date,type:res.rows.item(i).type,description:res.rows.item(i).description,amount:res.rows.item(i).amount})
      }
    })
    .catch(e => console.log(e));
    db.executeSql('SELECT SUM(amount) AS totalIncome FROM expense WHERE type="Income"', {})
    .then(res => {
      if(res.rows.length>0) {
        this.totalIncome = parseInt(res.rows.item(0).totalIncome);
        this.balance = this.totalIncome-this.totalExpense;
      }
    })
    .catch(e => console.log(e));
    db.executeSql('SELECT SUM(amount) AS totalExpense FROM expense WHERE type="Expense"', {})
    .then(res => {
      if(res.rows.length>0) {
        this.totalExpense = parseInt(res.rows.item(0).totalExpense);
        this.balance = this.totalIncome-this.totalExpense;
      }
    })
  }).catch(e => console.log(e));
}

addData() {
  this.navCtrl.push(AddDataPage);
}

editData(rowid) {
  this.navCtrl.push(EditDataPage, {
    rowid:rowid
  });
}

deleteData(rowid) {
  this.sqlite.create({
    name: 'ionicdb.db',
    location: 'default'
  }).then((db: SQLiteObject) => {
    db.executeSql('DELETE FROM expense WHERE rowid=?', [rowid])
    .then(res => {
      console.log(res);
      this.getData();
    })
    .catch(e => console.log(e));
  }).catch(e => console.log(e));
}

接下来,打开并编辑 src/pages/home/home.html 然后用它替换所有代码。

<ion-header>
  <ion-navbar>
    <ion-title>
      My Expense
    </ion-title>
    <ion-buttons end>
      <button ion-button icon-only (click)="addData()">
        <ion-icon name="add-circle"></ion-icon>
      </button>
    </ion-buttons>
  </ion-navbar>
</ion-header>

<ion-content padding>
  <h2>Expense List</h2>
  <ion-list>
    <ion-item-sliding *ngFor="let expense of expenses; let i=index">
      <ion-item nopadding>
        <p>
          <span>{{expense.date}}</span><br>
          Type: {{expense.type}}<br>
          {{expense.description}}
        </p>
        <h3 item-end>
          Amount: ${{expense.amount}}
        </h3>
      </ion-item>
      <ion-item-options side="right">
        <button ion-button color="primary" (click)="editData(expense.rowid)">
          <ion-icon name="paper"></ion-icon>
        </button>
        <button ion-button color="danger" (click)="deleteData(expense.rowid)">
          <ion-icon name="trash"></ion-icon>
        </button>
      </ion-item-options>
    </ion-item-sliding>
  </ion-list>
</ion-content>
<ion-footer>
  <ion-toolbar>
    <ion-title>Balance: ${{balance}}</ion-title>
  </ion-toolbar>
</ion-footer>

键入此命令以创建用于添加新数据的新页面。

ionic g page AddData

打开并编辑 src/pages/add-data/add-data.ts 然后用它替换所有代码。

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';
import { Toast } from '@ionic-native/toast';

@IonicPage()
@Component({
  selector: 'page-add-data',
  templateUrl: 'add-data.html',
})
export class AddDataPage {

  data = { date:"", type:"", description:"", amount:0 };

  constructor(public navCtrl: NavController,
    public navParams: NavParams,
    private sqlite: SQLite,
    private toast: Toast) {}

  saveData() {
    this.sqlite.create({
      name: 'ionicdb.db',
      location: 'default'
    }).then((db: SQLiteObject) => {
      db.executeSql('INSERT INTO expense VALUES(NULL,?,?,?,?)',[this.data.date,this.data.type,this.data.description,this.data.amount])
        .then(res => {
          console.log(res);
          this.toast.show('Data saved', '5000', 'center').subscribe(
            toast => {
              this.navCtrl.popToRoot();
            }
          );
        })
        .catch(e => {
          console.log(e);
          this.toast.show(e, '5000', 'center').subscribe(
            toast => {
              console.log(toast);
            }
          );
        });
    }).catch(e => {
      console.log(e);
      this.toast.show(e, '5000', 'center').subscribe(
        toast => {
          console.log(toast);
        }
      );
    });
  }

}

接下来,打开并编辑 src/pages/add-data/add-data.html 然后用它替换所有代码。

<ion-header>

  <ion-navbar>
    <ion-title>My Expense</ion-title>
  </ion-navbar>

</ion-header>

<ion-content padding>
  <h2>Add Data</h2>
  <form (ngSubmit)="saveData()">
    <ion-item>
      <ion-label>Date</ion-label>
      <ion-datetime displayFormat="MM/DD/YYYY" [(ngModel)]="data.date" name="date" required=""></ion-datetime>
    </ion-item>
    <ion-item>
      <ion-label>Type</ion-label>
      <ion-select [(ngModel)]="data.type" name="type" required="">
        <ion-option value="Income">Income</ion-option>
        <ion-option value="Expense">Expense</ion-option>
      </ion-select>
    </ion-item>
    <ion-item>
      <ion-label>Description</ion-label>
      <ion-input type="text" placeholder="Description" [(ngModel)]="data.description" name="description" required="" ></ion-input>
    </ion-item>
    <ion-item>
      <ion-label>Amount</ion-label>
      <ion-input type="number" placeholder="Amount" [(ngModel)]="data.amount" name="amount" required="" ></ion-input>
    </ion-item>
    <button ion-button type="submit" block>Save Data</button>
  </form>
</ion-content>

键入此命令以创建用于编辑数据的新页面。

ionic g page EditData

打开并编辑 src/pages/edit-data/edit-data.ts 然后用它替换所有代码。

import { Component } from '@angular/core';
import { IonicPage, NavController, NavParams } from 'ionic-angular';
import { SQLite, SQLiteObject } from '@ionic-native/sqlite';
import { Toast } from '@ionic-native/toast';

@IonicPage()
@Component({
  selector: 'page-edit-data',
  templateUrl: 'edit-data.html',
})
export class EditDataPage {

  data = { rowid:0, date:"", type:"", description:"", amount:0 };

  constructor(public navCtrl: NavController,
    public navParams: NavParams,
    private sqlite: SQLite,
    private toast: Toast) {
      this.getCurrentData(navParams.get("rowid"));
  }

  getCurrentData(rowid) {
    this.sqlite.create({
      name: 'ionicdb.db',
      location: 'default'
    }).then((db: SQLiteObject) => {
      db.executeSql('SELECT * FROM expense WHERE rowid=?', [rowid])
        .then(res => {
          if(res.rows.length > 0) {
            this.data.rowid = res.rows.item(0).rowid;
            this.data.date = res.rows.item(0).date;
            this.data.type = res.rows.item(0).type;
            this.data.description = res.rows.item(0).description;
            this.data.amount = res.rows.item(0).amount;
          }
        })
        .catch(e => {
          console.log(e);
          this.toast.show(e, '5000', 'center').subscribe(
            toast => {
              console.log(toast);
            }
          );
        });
    }).catch(e => {
      console.log(e);
      this.toast.show(e, '5000', 'center').subscribe(
        toast => {
          console.log(toast);
        }
      );
    });
  }

  updateData() {
    this.sqlite.create({
      name: 'ionicdb.db',
      location: 'default'
    }).then((db: SQLiteObject) => {
      db.executeSql('UPDATE expense SET date=?,type=?,description=?,amount=? WHERE rowid=?',[this.data.date,this.data.type,this.data.description,this.data.amount,this.data.rowid])
        .then(res => {
          console.log(res);
          this.toast.show('Data updated', '5000', 'center').subscribe(
            toast => {
              this.navCtrl.popToRoot();
            }
          );
        })
        .catch(e => {
          console.log(e);
          this.toast.show(e, '5000', 'center').subscribe(
            toast => {
              console.log(toast);
            }
          );
        });
    }).catch(e => {
      console.log(e);
      this.toast.show(e, '5000', 'center').subscribe(
        toast => {
          console.log(toast);
        }
      );
    });
  }

}

接下来,打开并编辑 src/pages/edit-data/edit-data.html 然后用它替换所有代码。

<ion-header>

  <ion-navbar>
    <ion-title>My Expense</ion-title>
  </ion-navbar>

</ion-header>

<ion-content padding>
  <h2>Edit Data</h2>
  <form (ngSubmit)="updateData()">
    <ion-item>
      <ion-label>Date</ion-label>
      <ion-datetime displayFormat="MM/DD/YYYY" [(ngModel)]="data.date" name="date" required=""></ion-datetime>
    </ion-item>
    <ion-item>
      <ion-label>Type</ion-label>
      <ion-select [(ngModel)]="data.type" name="type" required="">
        <ion-option value="Income">Income</ion-option>
        <ion-option value="Expense">Expense</ion-option>
      </ion-select>
    </ion-item>
    <ion-item>
      <ion-label>Description</ion-label>
      <ion-input type="text" placeholder="Description" [(ngModel)]="data.description" name="description" required="" ></ion-input>
    </ion-item>
    <ion-item>
      <ion-label>Amount</ion-label>
      <ion-input type="number" placeholder="Amount" [(ngModel)]="data.amount" name="amount" required="" ></ion-input>
    </ion-item>
    <ion-input type="hidden" [(ngModel)]="data.rowid" name="rowid"></ion-input>
    <button ion-button type="submit" block>Update Data</button>
  </form>
</ion-content>

在设备上运行 Ionic 3、Angular 4 和 SQLite 应用程序之前,请先移除并添加平台。

ionic cordova platform rm android
ionic cordova platform rm ios
ionic cordova platform add android
ionic cordova platform add ios

现在,回到当前文件夹后运行应用程序。

iOS 版

ionic cordova run ios

除了 UI 行为外,Android 应该与 iOS 相同。您可以通过键入此命令来运行。

ionic cordova run android

问候。

关于mysql - 有没有办法可以在 Ionic 2 中同步 MySQL 服务器和 SQlite?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/46888853/

有关mysql - 有没有办法可以在 Ionic 2 中同步 MySQL 服务器和 SQlite?的更多相关文章

  1. ruby - 具有身份验证的私有(private) Ruby Gem 服务器 - 2

    我想安装一个带有一些身份验证的私有(private)Rubygem服务器。我希望能够使用公共(public)Ubuntu服务器托管内部gem。我读到了http://docs.rubygems.org/read/chapter/18.但是那个没有身份验证-如我所见。然后我读到了https://github.com/cwninja/geminabox.但是当我使用基本身份验证(他们在他们的Wiki中有)时,它会提示从我的服务器获取源。所以。如何制作带有身份验证的私有(private)Rubygem服务器?这是不可能的吗?谢谢。编辑:Geminabox问题。我尝试“捆绑”以安装新的gem..

  2. ruby-on-rails - 启动 Rails 服务器时 ImageMagick 的警告 - 2

    最近,当我启动我的Rails服务器时,我收到了一长串警告。虽然它不影响我的应用程序,但我想知道如何解决这些警告。我的估计是imagemagick以某种方式被调用了两次?当我在警告前后检查我的git日志时。我想知道如何解决这个问题。-bcrypt-ruby(3.1.2)-better_errors(1.0.1)+bcrypt(3.1.7)+bcrypt-ruby(3.1.5)-bcrypt(>=3.1.3)+better_errors(1.1.0)bcrypt和imagemagick有关系吗?/Users/rbchris/.rbenv/versions/2.0.0-p247/lib/ru

  3. ruby-on-rails - s3_direct_upload 在生产服务器中不工作 - 2

    在Rails4.0.2中,我使用s3_direct_upload和aws-sdkgems直接为s3存储桶上传文件。在开发环境中它工作正常,但在生产环境中它会抛出如下错误,ActionView::Template::Error(noimplicitconversionofnilintoString)在View中,create_cv_url,:id=>"s3_uploader",:key=>"cv_uploads/{unique_id}/${filename}",:key_starts_with=>"cv_uploads/",:callback_param=>"cv[direct_uplo

  4. ruby-on-rails - 在 Rails 中调试生产服务器 - 2

    您如何在Rails中的实时服务器上进行有效调试,无论是在测试版/生产服务器上?我试过直接在服务器上修改文件,然后重启应用,但是修改好像没有生效,或者需要很长时间(缓存?)我也试过在本地做“脚本/服务器生产”,但是那很慢另一种选择是编码和部署,但效率很低。有人对他们如何有效地做到这一点有任何见解吗? 最佳答案 我会回答你的问题,即使我不同意这种热修补服务器代码的方式:)首先,你真的确定你已经重启了服务器吗?您可以通过跟踪日志文件来检查它。您更改的代码显示的View可能会被缓存。缓存页面位于tmp/cache文件夹下。您可以尝试手动删除

  5. ruby-on-rails - 有没有办法为 CarrierWave/Fog 设置上传进度指示器? - 2

    我在Rails应用程序中使用CarrierWave/Fog将视频上传到AmazonS3。有没有办法判断上传的进度,让我可以显示上传进度如何? 最佳答案 CarrierWave和Fog本身没有这种功能;你需要一个前端uploader来显示进度。当我不得不解决这个问题时,我使用了jQueryfileupload因为我的堆栈中已经有jQuery。甚至还有apostonCarrierWaveintegration因此您只需按照那里的说明操作即可获得适用于您的应用的进度条。 关于ruby-on-r

  6. 使用canal同步MySQL数据到ES - 2

    文章目录一、概述简介原理模块二、配置Mysql使用版本环境要求1.操作系统2.mysql要求三、配置canal-server离线下载在线下载上传解压修改配置单机配置集群配置分库分表配置1.修改全局配置2.实例配置垂直分库水平分库3.修改group-instance.xml4.启动监听四、配置canal-adapter1修改启动配置2配置映射文件3启动ES数据同步查询所有订阅同步数据同步开关启动4.验证五、配置canal-admin一、概述简介canal是Alibaba旗下的一款开源项目,Java开发。基于数据库增量日志解析,提供增量数据订阅&消费。Git地址:https://github.co

  7. ruby - 是否可以在不实际发送或读取数据的情况下查明 ruby​​ 套接字是否处于 ESTABLISHED 或 CLOSE_WAIT 状态? - 2

    s=Socket.new(Socket::AF_INET,Socket::SOCK_STREAM,0)s.connect(Socket.pack_sockaddr_in('port','hostname'))ssl=OpenSSL::SSL::SSLSocket.new(s,sslcert)ssl.connect从这里开始,如果ssl连接和底层套接字仍然是ESTABLISHED,或者它是否在默认值7200之后进入CLOSE_WAIT,我想检查一个线程几秒钟甚至更糟的是在实际上不需要.write()或.read()的情况下关闭。是用select()、IO.select()还是其他方法完成

  8. ruby - 有没有办法从 ruby​​ case 语句中访问表达式? - 2

    我想从then子句中访问c​​ase语句表达式,即food="cheese"casefoodwhen"dip"then"carrotsticks"when"cheese"then"#{expr}crackers"else"mayo"end在这种情况下,expr是食物的当前值(value)。在这种情况下,我知道,我可以简单地访问变量food,但是在某些情况下,该值可能无法再访问(array.shift等)。除了将expr移出到局部变量然后访问它之外,是否有直接访问caseexpr值的方法?罗亚附注我知道这个具体示例很简单,只是一个示例场景。 最佳答案

  9. ruby - 我的 Ruby IRC 机器人没有连接到 IRC 服务器。我究竟做错了什么? - 2

    require"socket"server="irc.rizon.net"port="6667"nick="RubyIRCBot"channel="#0x40"s=TCPSocket.open(server,port)s.print("USERTesting",0)s.print("NICK#{nick}",0)s.print("JOIN#{channel}",0)这个IRC机器人没有连接到IRC服务器,我做错了什么? 最佳答案 失败并显示此消息::irc.shakeababy.net461*USER:Notenoughparame

  10. ruby-on-rails - 有没有一种工具可以在编码时自动保存对文件的增量更改? - 2

    我最喜欢的Google文档功能之一是它会在我工作时不断自动保存我的文档版本。这意味着即使我在进行关键更改之前忘记在某个点进行保存,也很有可能会自动创建一个保存点。至少,我可以将文档恢复到错误更改之前的状态,并从该点继续工作。对于在MacOS(或UNIX)上运行的Ruby编码器,是否有具有等效功能的工具?例如,一个工具会每隔几分钟自动将Gitcheckin我的本地存储库以获取我正在处理的文件。也许我有点偏执,但这点小保险可以让我在日常工作中安心。 最佳答案 虚拟机有些人可能讨厌我对此的回应,但我在编码时经常使用VIM,它具有自动保存功

随机推荐