Ionic 4:扫描 QR 码后将 data.json 中的布尔值更改为 true
Ionic 4: Change boolean in data.json to true after scanning a QR-Code
对于一个大学项目,我必须使用 Ionic 4 实现一个 Ionic 应用程序。
在应用程序中,您可以扫描二维码,它提供来自 JSON 文件的关于特定街头艺术的数据,并使用 cordova 插件将其显示在相机预览中。这很好用。
我现在尝试在扫描 QR 码后将 JSON-File 中的布尔值设置为 true,以便显示仅包含扫描的 QR 码数据的列表。
我曾尝试使用 Cordova 文件插件,但我无法让它正常工作。
setJson(fileName, object) {
this.file.writeFile(this.dataDirectory,this.fileName,
JSON.stringify(this.object), {append: true, replace: false});
}
目前我收到此错误:
EncodingError:提供给 API 的 URI 格式错误,或者生成的数据 URL 超出了数据 URL 的 URL 长度限制。
ar.page.ts:
import { Plugins } from '@capacitor/core';
import { Component, OnInit, Inject, ViewEncapsulation } from
'@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { JsonDataService } from '../../json-data.service';
import { DOCUMENT } from '@angular/common';
import { Toast } from '@ionic-native/toast/ngx';
import { Router, NavigationExtras } from '@angular/router';
import { NavController, ModalController } from '@ionic/angular';
import { File } from '@ionic-native/file/ngx';
import {
CameraPreview,
CameraPreviewOptions
} from '@ionic-native/camera-preview/ngx';
import { Platform } from '@ionic/angular';
import { ModalPagePage } from '../modal-page/modal-page.page';
const { Browser } = Plugins;
@Component({
selector: 'app-ar',
templateUrl: './ar.page.html',
styleUrls: ['./ar.page.scss'],
encapsulation: ViewEncapsulation.None
})
export class ArPage implements OnInit {
datenData = [];
selectedProduct: any;
productFound = false;
fileName = 'data.json';
dataDirectory = this.file.applicationDirectory + 'assets/data/';
object = {boolean: true};
constructor(
private barcodeScanner: BarcodeScanner,
private datenService: JsonDataService,
private toast: Toast,
private router: Router,
public modalController: ModalController,
public navCtrl: NavController,
private cameraPreview: CameraPreview,
private platform: Platform,
public file: File,
@Inject(DOCUMENT) private _document
) {
fetch('../../../assets/data/data.json')
.then(res => res.json())
.then(data => {
this.datenData = data.jsondata;
this.datenService.setJsondata(this.datenData);
console.log(data);
});
}
ngOnInit() {
this.qrscan();
}
qrscan() {
this.datenData = this.datenService.getJsondata();
this.selectedProduct = {};
this.barcodeScanner.scan().then(
barcodeData => {
this.selectedProduct = this.datenData.find(
daten => daten.qrcode === barcodeData.text
);
if (this.selectedProduct !== undefined) {
this.productFound = true;
this.setJson(this.fileName, this.object);
this.camerapreview();
this.showModal();
} else {
this.productFound = false;
this.router.navigate(['/tabs/tab2']);
this.toast
.show(`Product not found`, '5000', 'center')
.subscribe(toast => {
console.log(toast);
});
}
},
err => {
this.toast.show(err, '5000', 'center').subscribe(toast => {
console.log(toast);
this.router.navigate(['/tabs/tab2']);
});
}
);
}
setJson(fileName, object) {
this.file.writeFile(this.dataDirectory,this.fileName,
JSON.stringify(this.object), {append: true, replace: false});
}
}
data.json:
{
"jsondata": [
{
"id": 1,
"boolean": false,
"qrcode": "1",
"location": {
"latitude": 50.952952,
"longitude": 6.912467,
"street": "Venloer Str. 429"
},
"title": "Ohne dich würde ich mich nicht trauen.",
"artist": {
"name": "Jasmin Siddiqui und Falk Lehmann alias Herakut",
"website": "http://www.herakut.de"
},
"information": {
"text": "Auf dem Mural vom deutschen Street Art Duo Hera und Akut erkennt man ein kniendes Mädchen, die ihren Hund auf dem Arm hält. Ängstlich blickt sie in Richtung des Parks am Bürgerzentrum Ehrenfeld und hält ihren Hund schützend vor sich. Neben dem Hund steht „ohne dich würde ich mich nicht trauen“. Neben dem Mädchen kann man die Worte lesen: „we love even the scary looking ones“ . Man kann das Bild als einen Verweis auf das bunte und teils zwielichtige Treiben in naheliegenden Park verstehen.",
"gallery": {
"picturemap": "http://www.herakut.de/wp-content/uploads/2014/05/ko%CC%88ln.jpg",
"picturemapcredit": "http://www.herakut.de"
}
}
}
]
}
json.ts:
export interface Daten{
id: any;
boolean: boolean;
qrcode: string;
location: {
latitude: any;
longitude: any;
street: string;
};
title: string;
artist: {
name: string;
website: string;
};
information: {
text: string;
gallery: {
picturemap: string;
picturemapcredit: string;
};
};
}
这是它的 github 存储库:https://github.com/alexandrasophiapetersen/BananAR-Cologne
二维码可以在资产文件夹中找到。
这是我的第一个 Ionic 项目。
如果有人能帮助我,我将不胜感激。
非常感谢。
刚刚看了你的代码,感觉写的不错。
您尝试实现它的最后一次提交产生了一个微妙的错误:
使用 angular ngFor 它会在你放置的实际标签上循环,而不是在内容上循环,所以你最终会得到一个离子列表列表,而你之前拥有的是一个离子列表里面的离子项目列表。
您可以在与 ngFor
相同的行中使用 ngIf
,并引用您正在循环播放的内容 - 如果这就是您移动它的原因。
对于您的实际问题,我认为您不应该尝试将 json 文件转换为某种数据库。把它想象成一个提要。您可以轻松地将 json 文件放到网络服务器上,让每个用户加载它,并自动更新它支持的二维码,只需更改网络服务器文件即可。
将个人用户数据放入其中不是正确的想法。
相反,您应该查找有关 Ionic Storage 的教程。它为您提供了一个简单的获取设置界面,一旦在您的项目中配置,您就可以只为该用户加载数据。
保留一个单独的列表。您的 json 有一个 id
字段,因此您可以制作一个扫描代码数组并将 id 放入其中。然后对于每个项目,您可以通过查看当前项目的 id 是否在该数组中来检查当前项目是否已经被扫描过。
我一直将此作为一般性建议,因为我假设它是一个您想自己学习的 uni 项目,而不是冒着将定制的书面解决方案交给您并尝试提交的风险。如果你卡住了,我可以更新我的答案。
浏览代码时的一些其他想法:
给布尔值命名 boolean
是一种冒犯 :P 不要养成这样的糟糕名字的习惯。给它起一个描述性的名称,例如 isScanned
我看到你使用了一些原生的 toast 插件。也许你有理由这样做,但实际上有一个 toast 功能 built in to Ionic。我不确定你的教授给你打分的依据是什么,但我希望你尽可能使用内置组件。
对于一个大学项目,我必须使用 Ionic 4 实现一个 Ionic 应用程序。
在应用程序中,您可以扫描二维码,它提供来自 JSON 文件的关于特定街头艺术的数据,并使用 cordova 插件将其显示在相机预览中。这很好用。
我现在尝试在扫描 QR 码后将 JSON-File 中的布尔值设置为 true,以便显示仅包含扫描的 QR 码数据的列表。
我曾尝试使用 Cordova 文件插件,但我无法让它正常工作。
setJson(fileName, object) {
this.file.writeFile(this.dataDirectory,this.fileName,
JSON.stringify(this.object), {append: true, replace: false});
}
目前我收到此错误: EncodingError:提供给 API 的 URI 格式错误,或者生成的数据 URL 超出了数据 URL 的 URL 长度限制。
ar.page.ts:
import { Plugins } from '@capacitor/core';
import { Component, OnInit, Inject, ViewEncapsulation } from
'@angular/core';
import { BarcodeScanner } from '@ionic-native/barcode-scanner/ngx';
import { JsonDataService } from '../../json-data.service';
import { DOCUMENT } from '@angular/common';
import { Toast } from '@ionic-native/toast/ngx';
import { Router, NavigationExtras } from '@angular/router';
import { NavController, ModalController } from '@ionic/angular';
import { File } from '@ionic-native/file/ngx';
import {
CameraPreview,
CameraPreviewOptions
} from '@ionic-native/camera-preview/ngx';
import { Platform } from '@ionic/angular';
import { ModalPagePage } from '../modal-page/modal-page.page';
const { Browser } = Plugins;
@Component({
selector: 'app-ar',
templateUrl: './ar.page.html',
styleUrls: ['./ar.page.scss'],
encapsulation: ViewEncapsulation.None
})
export class ArPage implements OnInit {
datenData = [];
selectedProduct: any;
productFound = false;
fileName = 'data.json';
dataDirectory = this.file.applicationDirectory + 'assets/data/';
object = {boolean: true};
constructor(
private barcodeScanner: BarcodeScanner,
private datenService: JsonDataService,
private toast: Toast,
private router: Router,
public modalController: ModalController,
public navCtrl: NavController,
private cameraPreview: CameraPreview,
private platform: Platform,
public file: File,
@Inject(DOCUMENT) private _document
) {
fetch('../../../assets/data/data.json')
.then(res => res.json())
.then(data => {
this.datenData = data.jsondata;
this.datenService.setJsondata(this.datenData);
console.log(data);
});
}
ngOnInit() {
this.qrscan();
}
qrscan() {
this.datenData = this.datenService.getJsondata();
this.selectedProduct = {};
this.barcodeScanner.scan().then(
barcodeData => {
this.selectedProduct = this.datenData.find(
daten => daten.qrcode === barcodeData.text
);
if (this.selectedProduct !== undefined) {
this.productFound = true;
this.setJson(this.fileName, this.object);
this.camerapreview();
this.showModal();
} else {
this.productFound = false;
this.router.navigate(['/tabs/tab2']);
this.toast
.show(`Product not found`, '5000', 'center')
.subscribe(toast => {
console.log(toast);
});
}
},
err => {
this.toast.show(err, '5000', 'center').subscribe(toast => {
console.log(toast);
this.router.navigate(['/tabs/tab2']);
});
}
);
}
setJson(fileName, object) {
this.file.writeFile(this.dataDirectory,this.fileName,
JSON.stringify(this.object), {append: true, replace: false});
}
}
data.json:
{
"jsondata": [
{
"id": 1,
"boolean": false,
"qrcode": "1",
"location": {
"latitude": 50.952952,
"longitude": 6.912467,
"street": "Venloer Str. 429"
},
"title": "Ohne dich würde ich mich nicht trauen.",
"artist": {
"name": "Jasmin Siddiqui und Falk Lehmann alias Herakut",
"website": "http://www.herakut.de"
},
"information": {
"text": "Auf dem Mural vom deutschen Street Art Duo Hera und Akut erkennt man ein kniendes Mädchen, die ihren Hund auf dem Arm hält. Ängstlich blickt sie in Richtung des Parks am Bürgerzentrum Ehrenfeld und hält ihren Hund schützend vor sich. Neben dem Hund steht „ohne dich würde ich mich nicht trauen“. Neben dem Mädchen kann man die Worte lesen: „we love even the scary looking ones“ . Man kann das Bild als einen Verweis auf das bunte und teils zwielichtige Treiben in naheliegenden Park verstehen.",
"gallery": {
"picturemap": "http://www.herakut.de/wp-content/uploads/2014/05/ko%CC%88ln.jpg",
"picturemapcredit": "http://www.herakut.de"
}
}
}
]
}
json.ts:
export interface Daten{
id: any;
boolean: boolean;
qrcode: string;
location: {
latitude: any;
longitude: any;
street: string;
};
title: string;
artist: {
name: string;
website: string;
};
information: {
text: string;
gallery: {
picturemap: string;
picturemapcredit: string;
};
};
}
这是它的 github 存储库:https://github.com/alexandrasophiapetersen/BananAR-Cologne
二维码可以在资产文件夹中找到。
这是我的第一个 Ionic 项目。 如果有人能帮助我,我将不胜感激。
非常感谢。
刚刚看了你的代码,感觉写的不错。
您尝试实现它的最后一次提交产生了一个微妙的错误:
使用 angular ngFor 它会在你放置的实际标签上循环,而不是在内容上循环,所以你最终会得到一个离子列表列表,而你之前拥有的是一个离子列表里面的离子项目列表。
您可以在与 ngFor
相同的行中使用 ngIf
,并引用您正在循环播放的内容 - 如果这就是您移动它的原因。
对于您的实际问题,我认为您不应该尝试将 json 文件转换为某种数据库。把它想象成一个提要。您可以轻松地将 json 文件放到网络服务器上,让每个用户加载它,并自动更新它支持的二维码,只需更改网络服务器文件即可。
将个人用户数据放入其中不是正确的想法。
相反,您应该查找有关 Ionic Storage 的教程。它为您提供了一个简单的获取设置界面,一旦在您的项目中配置,您就可以只为该用户加载数据。
保留一个单独的列表。您的 json 有一个 id
字段,因此您可以制作一个扫描代码数组并将 id 放入其中。然后对于每个项目,您可以通过查看当前项目的 id 是否在该数组中来检查当前项目是否已经被扫描过。
我一直将此作为一般性建议,因为我假设它是一个您想自己学习的 uni 项目,而不是冒着将定制的书面解决方案交给您并尝试提交的风险。如果你卡住了,我可以更新我的答案。
浏览代码时的一些其他想法:
给布尔值命名 boolean
是一种冒犯 :P 不要养成这样的糟糕名字的习惯。给它起一个描述性的名称,例如 isScanned
我看到你使用了一些原生的 toast 插件。也许你有理由这样做,但实际上有一个 toast 功能 built in to Ionic。我不确定你的教授给你打分的依据是什么,但我希望你尽可能使用内置组件。