密码
我的产品组件。
这不是完整的代码。我删除了代码的某些部分,比如与后端相关的服务器调用和调用。
import {Component, EventEmitter, Input, OnChanges, OnInit, Output} from '@angular/core';
import { DataProvider } from 'src/app/providers/data.provider';
import { AuthService } from 'src/app/services/auth.service';
import { InventoryService } from 'src/app/services/inventory.service';
@Component({
selector: 'app-wide-product-card',
templateUrl: './wide-product-card.component.html',
styleUrls: ['./wide-product-card.component.css']
})
export class WideProductCardComponent implements OnInit,OnChanges {
@Input() img:string = "https://source.unsplash.com/650x940"
@Input() orderTitle:string = "ArtWork Product"
@Input() orderDescription:string = "Lorem ipsum dolor sit amet, consectetur\n" +
" adipiscing elit. Curabitur cursus tincidunt\n" +
" commodo. Nunc justo nisi, vestibulum."
@Input() orderprice:number = 2300;
@Input() category:string;
@Input() subcategory:string;
@Input() productId:string
@Input() extras:any;
@Input() orderconfig:string = "Chosen config"
@Input() quantity:number = 1;
@Input() identifier:string="";
@Input() configData:any;
db:any={};
@Input() showConfig:boolean = true;
@Input() showActions:boolean = true;
@Input() showQuantity:boolean = false;
@Input() showImageInput:boolean = false;
@Output() changeQuantity : EventEmitter<any> = new EventEmitter();
@Output() addImage: EventEmitter<any> = new EventEmitter();
@Output() removeEvent: EventEmitter<any> = new EventEmitter();
constructor(public inventoryService: InventoryService,private authService: AuthService,private dataProvider: DataProvider) { }
changeImage(image){
if (image.target.files[0].size < 500000){
this.dataProvider.data=this.identifier;
const a:any = {productId:this.productId,image:image.target.files[0],refData:this.identifier}
console.log("Event logging just before emitting the event from function changeImage(event)",this.identifier)
this.addImage.emit(a);
this.authService.presentToast("Image added successfully")
} else {
this.authService.presentToast("Image size should be less than 500kb",3000)
}
}
removeFromWishlist(){
this.removeEvent.emit({productId:this.productId,ref:this.identifier})
}
removeQuantity(){
this.quantity=this.quantity-1
this.changeQuantity.emit({quantity:this.quantity,productId:this.productId,ref:this.identifier});
}
addQuantity(){
this.quantity=this.quantity+1
this.changeQuantity.emit({quantity:this.quantity,productId:this.productId,ref:this.identifier});
}
ngOnInit(){
console.log('Event value emitted from ngOnInit()',this.identifier)
}
ngOnChanges(){
console.log('Event value emitted from OnChanges() from child component',this.identifier)
}
}我的组件html
<div class="order-card">
<img [src]="img" alt="{{orderTitle}}" class="order-img">
<div class="order">
<div class="order-details">
<h4 class="order-title">{{orderTitle}}</h4>
<p class="order-description">{{orderDescription}}</p>
</div>
<div class="order-price-and-btns">
<p class="order-price">Price: ₹{{orderprice * quantity}}</p>
<ion-button *ngIf="showActions" class="order-remove" (click)="removeFromWishlist()">Remove</ion-button>
<ion-button *ngIf="showActions" class="order-view"
href="./product?productId={{this.productId}}">View
Product</ion-button>
<ion-item button lines="none" *ngIf="showImageInput">
<input type="file" name="file" max="1" (change)="changeImage($event)" id="file" class="inputfile" />
<label for="file">Choose a file</label>
</ion-item>
</div>
</div>
<div class="order-config">
<h4 class="chosen-config">{{orderconfig}}</h4>
<ion-list>
<ion-item *ngFor="let configitem of configData">
<ion-label>{{configitem.title}}</ion-label>
<ion-icon name="arrow-forward"></ion-icon>
<ion-label>{{configitem.value}}</ion-label>
</ion-item>
</ion-list>
<div *ngIf="showQuantity">
<ion-item lines="none">
<button slot="start" [disabled]="quantity<=1" (click)="removeQuantity()">
<ion-icon name="remove"></ion-icon>
</button>
<ion-label color="primary" >{{quantity}}</ion-label>
<button [disabled]="quantity>=10" slot="end" (click)="addQuantity()">
<ion-icon name="add"></ion-icon>
</button>
</ion-item>
</div>
</div>
</div>我的父页面
import { ChangeDetectorRef, Component, OnInit } from '@angular/core';
import { AngularFirestore } from '@angular/fire/firestore';
import { ModalController } from '@ionic/angular';
import { InvoiceDetailComponent } from 'src/app/modals/invoice-detail/invoice-detail.component';
import {
FormBuilder,
FormControl,
FormGroup,
Validators,
} from '@angular/forms';
import { Router } from '@angular/router';
import { DataProvider } from 'src/app/providers/data.provider';
import { AuthService } from 'src/app/services/auth.service';
import { InventoryService } from 'src/app/services/inventory.service';
import { PaymentService } from 'src/app/services/payment.service';
import { environment } from 'src/environments/environment';
import firebase from 'firebase/app';
import { AngularFireAnalytics } from '@angular/fire/analytics';
import { InvoiceService } from 'src/app/services/invoice.service';
@Component({
selector: 'app-checkout',
templateUrl: './checkout.component.html',
styleUrls: ['./checkout.component.scss'],
})
export class CheckoutComponent implements OnInit {
dataCopy;
constructor(
private afs: AngularFirestore,
public dataProvider: DataProvider,
private paymentService: PaymentService,
private changeRef: ChangeDetectorRef,
private authService: AuthService,
private formbuilder: FormBuilder,
private inventoryService: InventoryService,
private router: Router,
private analytics: AngularFireAnalytics,
public modalController: ModalController,
private invoiceService: InvoiceService,
) {
this.form = this.formbuilder.group({
firstName: this.firstName,
lastName: this.lastName,
email: this.email,
phoneNumber: this.phoneNumber,
addressLine1: this.addressLine1,
city: this.city,
pincode: this.pincode,
state: this.state,
country: this.country,
message: this.message,
santaCredit: this.santaCredit,
});
}
form: FormGroup;
firstName: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(5),
Validators.pattern('[a-zA-Z ]*'),
]);
lastName: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(5),
Validators.pattern('[a-zA-Z ]*'),
]);
email: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(5),
Validators.email,
]);
phoneNumber: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(10),
Validators.maxLength(10),
Validators.pattern('[0-9]{10}'),
]);
addressLine1: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(5),
]);
city: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(5),
Validators.pattern('[a-zA-Z ]*'),
]);
pincode: FormControl = new FormControl('', [
Validators.required,
Validators.pattern('[0-9]*'),
]);
state: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(5),
Validators.pattern('[a-zA-Z ]*'),
]);
country: FormControl = new FormControl('', [
Validators.required,
Validators.minLength(5),
Validators.pattern('[a-zA-Z ]*'),
]);
santaCredit: FormControl = new FormControl(false, [Validators.required]);
message: FormControl = new FormControl('', [
Validators.minLength(10),
Validators.maxLength(100),
]);
orders = [];
objectKeys = Object.keys;
quantity = 1;
offerFlat: number = 0;
payableAmount = 0;
WindowRef: any;
processingPayment: boolean;
paymentResponse: any = {};
orderItems = [];
santaCoins: number = 0;
imageRequired: any = [];
imagesValid: boolean = false;
log(data) {
// console.log(data);
}
addImage(event) {
console.log('Event recieved by the addImage(event) eventHandler function', event);
let allValid = true;
// console.log('imageRequiredLEngth', this.imageRequired,event,this.dataProvider.data);
this.imageRequired.forEach((data, index) => {
if (data.ref == event.refData) {
this.imageRequired[index].imageReference = event.image;
}
if (data.imageReference == undefined) {
allValid = false;
}
});
this.imagesValid = allValid;
// console.log('imageRequired', this.imageRequired);
}
presentInvoice() {
}
get grandTotal(): number {
var total = 0;
this.dataCopy.forEach((order) => {
total += order.price * order.quantity;
});
return total - this.offerFlat;
}
get grandHeight(): number {
var total = 0;
this.orders.forEach((order) => {
total += order.finalPrice;
});
return total;
}
setCashback(event) {
if (event.detail.checked) {
this.offerFlat = this.santaCoins;
} else {
this.offerFlat = 0;
}
}
ngOnInit() {
this.dataProvider.showOverlay = false;
this.inventoryService
.getUserInfo()
.ref.get()
.then((user: any) => {
this.santaCoins = user.data().totalCashback;
});
if (this.dataProvider.checkOutdata) {
this.dataCopy = this.dataProvider.checkOutdata;
this.dataProvider.checkOutdata.forEach((prod) => {
// console.log('prod from checkoutdata', prod);
var docRef = this.afs.collection('products').ref.doc(prod.productData);
docRef.get().then((data) => {
if (data.exists) {
// console.log('Document data:', data);
let dat: any = data.data();
if (dat.imageReference) {
this.imagesValid = false;
// console.log('identifier >>>',prod.identifier);
this.imageRequired.push({
productId: dat.productId,
ref: prod.identifier,
imageReference: undefined,
});
// console.log('imageRequired', this.imageRequired,this.imageRequired.length);
}
this.orderItems.push({
name: dat.productName,
sku: prod.productData,
units: 1,
selling_price: prod.price - this.offerFlat,
});
// console.log('identifier >>>',prod.identifier);
dat['finalPrice'] = prod.price;
dat['selections'] = prod.extrasData;
dat['quantity'] = prod.quantity;
dat['ref']=prod.identifier;
dat['cartId']=prod.cartId;
let config = []
for (let key of Object.keys(dat.selections)) {
let selection = dat.selections[key];
if (selection.type == 'textSel' || selection.type == 'imgSel'){
config.push({title:selection.sectionTitle,value:selection.title});
} else if (selection.type == 'faceCount'){
config.push({title:'Faces',value:selection.faces});
}
}
dat['config'] = config;
// console.log('dat data dt',dat);
this.orders.push(dat);
} else {
// console.log('No such document!');
}
});
});
this.WindowRef = this.paymentService.WindowRef;
} else {
this.authService.presentToast('Oh Ohh! Checkout expired 😅');
this.router.navigate(['']);
}
}
proceedToPay($event) {
console.log('imagereq',this.imageRequired)
console.log('imageVald',this.imagesValid)
if (this.imagesValid) {
this.dataProvider.showOverlay = true;
this.processingPayment = true;
this.payableAmount = this.grandTotal * 100;
this.imageRequired.forEach((data, index) => {
console.log(data);
})
// console.log('payable amount', this.payableAmount);
// this.initiatePaymentModal($event);
// this.analytics.logEvent('Checkout');
} else {
this.authService.presentToast('Please add all images by pressing Choose a file on every product.');
}
}
initiatePaymentModal(event) {
let receiptNumber = `Receipt#${Math.floor(Math.random() * 5123 * 43) + 10}`;
let orderDetails = {
amount: this.payableAmount,
receipt: receiptNumber,
};
this.paymentService.createOrder(orderDetails).subscribe(
(order) => {
console.log(
'TCL: CheckoutComponent -> initiatePaymentModal -> order',
order
);
var rzp1 = new this.WindowRef.Razorpay(
this.preparePaymentDetails(order)
);
this.processingPayment = false;
rzp1.open();
event.preventDefault();
},
(error) => {
console.log(
'TCL: CheckoutComponent -> initiatePaymentModal -> error',
error
);
this.authService.presentToast(error.message);
this.processingPayment = false;
}
);
}
preparePaymentDetails(order) {
var ref = this;
return {
key: environment.RAZORPAY_KEY_ID, // Enter the Key ID generated from the Dashboard
amount: this.payableAmount, // Amount is in currency subunits. Default currency is INR. Hence, 29935 refers to 29935 paise or INR 299.35.
name: 'Pay',
currency: order.currency,
order_id: order.id, //This is a sample Order ID. Create an Order using Orders API. (https://razorpay.com/docs/payment-gateway/orders/integration/#step-1-create-an-order). Refer the Checkout form table given below
image: 'https://angular.io/assets/images/logos/angular/angular.png',
handler: function (response) {
ref.handlePayment(response);
},
prefill: {
name:
this.form.get('firstName')!.value.toString() +
this.form.get('lastName')!.value.toString(),
email: this.form.get('email')!.value,
contact: this.form.get('phoneNumber')!.value,
},
theme: {
color: '#2874f0',
},
};
}
handlePayment(response) {
this.paymentService
.capturePayment({
amount: this.payableAmount,
payment_id: response.razorpay_payment_id,
})
.subscribe(
(res) => {
if (this.offerFlat > 0) {
this.inventoryService.updateUserData({ totalCashback: 0 });
}
this.paymentResponse = res;
this.changeRef.detectChanges();
console.log('success response', this.paymentResponse);
const shippingDetail = {
order_id: `Order#${
Math.floor(Math.random() * 5123435345 * 43) + 10
}`,
billing_customer_name: this.form.get('firstName')!.value,
billing_last_name: this.form.get('lastName')!.value,
billing_city: this.form.get('city')!.value,
billing_pincode: this.form.get('pincode')!.value,
billing_state: this.form.get('state')!.value,
billing_country: this.form.get('country')!.value,
billing_email: this.form.get('email')!.value,
billing_phone: this.form.get('phoneNumber')!.value,
billing_address: this.form.get('addressLine1')!.value,
order_items: this.orderItems,
payment_method: 'Prepaid',
sub_total: this.grandTotal,
length: 1,
height: 1,
weight: 1,
breadth: 1,
};
console.log('shippingDetail', shippingDetail);
this.paymentService.shipOrder(shippingDetail).subscribe(
(res: any) => {
this.authService.presentToast('Payment Successful 😊');
console.log('shipping Confirmed Detail', res);
let currentOrder = {
shippingDetail: res.body,
products: this.orders,
orderStage: 'live',
orderId: res.body.order_id,
shipment_id: res.body.shipment_id,
orderConfirmed: false,
grandTotal:this.grandTotal,
orderMessage: this.message.value || '',
};
this.inventoryService.addUserOrder(currentOrder);
let detail = {
name:shippingDetail.billing_customer_name,
address: shippingDetail.billing_address,
city: shippingDetail.billing_city,
state: shippingDetail.billing_state,
country: shippingDetail.billing_country,
pincode: shippingDetail.billing_pincode,
mobile: shippingDetail.billing_phone,
email: shippingDetail.billing_email,
discount:{available:true,code:'offerCode',price:120},
grandTotal:this.grandTotal,
taxCharges:(this.grandTotal/100)*15,
}
this.invoiceService.createInvoice(this.orders,detail);
this.dataProvider.shippingData =
currentOrder.shippingDetail.shipment_id.toString();
this.authService.presentToast('Order Placed Successfully ');
this.router.navigateByUrl(
'trackorder?shippingId=' +
currentOrder.shippingDetail.shipment_id.toString()
);
},
(error) => {
this.paymentResponse = error;
this.authService.presentToast(
error.message +
'\nPlease contact hello santa, to complete your order',
7000
);
console.log('Error occured while completing shipment');
}
);
},
(error) => {
this.paymentResponse = error;
console.log('failed response', this.paymentResponse);
}
);
}
}父组件的Html。
<ion-content [ngStyle]="{'filter': (dataProvider.showOverlay) ? 'blur(10px)' : 'blur(0px)' }">
<app-header></app-header>
<div class="home">
<div class="uk-panel">
<div class="inner-box" align="center">
<main id="container">
<h2 id="checkout-title">Checkout</h2>
<section id="orders-card">
<div class="product-row">
<app-wide-product-card *ngFor="let order of orders" [img]="order.productImages[0].image"
[orderTitle]="order.productName" [identifier]="order.ref" [configData]="order.config" [showActions]="false" [orderDescription]="order.seoDescription"
[orderprice]="order.finalPrice" (addImage)="addImage($event)" [productId]="order.productId" [quantity]="order.quantity" [showImageInput]="order.imageReference" [showQuantity]="false"></app-wide-product-card>
</div>
</section>
<section id="orders-table-container">
<table id="orders-table">
<thead id="orders-table-head">
<tr>
<th>Product Name</th>
<th>Quantity</th>
<th>Price</th>
<th>Total Price</th>
</tr>
</thead>
<tbody>
<tr *ngFor="let order of orders">
<td>{{order.productName}}</td>
<td>{{order.quantity}}</td>
<td>{{order.productPrice}}</td>
<td>{{order.finalPrice*order.quantity}}</td>
</tr>
</tbody>
<tfoot>
<tr>
<td></td>
<td></td>
<td>Grand Total</td>
<td>{{grandTotal}}</td>
</tr>
</tfoot>
</table>
</section>
<ion-card>
<h1 style="text-align: center">
Delivery info
</h1>
<ion-list>
<form [formGroup]="form" (ngSubmit)="proceedToPay($event)" method="POST">
<ion-item>
<ion-label position="floating">
Your First Name
</ion-label>
<ion-input type="text" placeholder="Your Name" formControlName="firstName" required></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
Your Last Name
</ion-label>
<ion-input type="text" placeholder="Your Name" formControlName="lastName" required></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
Your Email
</ion-label>
<ion-input type="text" placeholder="Enter Your Email" formControlName="email" required>
</ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
Your Phone number
</ion-label>
<ion-input type="integer" placeholder="Enter Your Phone number" formControlName="phoneNumber"
required></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
delivery address(including house number)
</ion-label>
<ion-input type="text" placeholder="delivery address(including house number)"
formControlName="addressLine1" required></ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
city
</ion-label>
<ion-input type="text" placeholder="enter your city" required formControlName="city">
</ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
Pincode
</ion-label>
<ion-input type="text" placeholder="Enter Your Pincode" required formControlName="pincode">
</ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
State
</ion-label>
<ion-input type="text" placeholder="Enter Your State" required formControlName="state">
</ion-input>
</ion-item>
<ion-item>
<ion-label position="floating">
Country
</ion-label>
<ion-input type="text" placeholder="Enter Your country" required formControlName="country">
</ion-input>
</ion-item>
<ion-item>
<input type="checkbox" #checkbox (change)="log(checkbox)">
<ion-label> Add a message</ion-label>
</ion-item>
<ion-item *ngIf="checkbox.checked">
<ion-label position="floating">Your Message</ion-label>
<ion-textarea placeholder="Enter your message" formControlName="message"></ion-textarea>
</ion-item>
<ion-item *ngIf="santaCoins>0">
<ion-checkbox [checked]="false" formControlName="santaCredit" (ionChange)="setCashback($event)"></ion-checkbox>
<ion-label> Use Your {{santaCoins}} Santa Credit for <strong>₹{{this.santaCoins}}</strong> off.</ion-label>
</ion-item>
<div align="center">
<!-- TODO [disabled]="!form.valid" -->
<button type="submit" >
<div *ngIf="processingPayment">
<ion-spinner name="crescent"></ion-spinner> Processing
</div>
<div *ngIf="!processingPayment">
Proceed to Pay
</div>
</button>
</div>
</form>
</ion-list>
</ion-card>
</main>
</div>
</div>
</div>
<app-footer></app-footer>
</ion-content>
<div id="overlay" *ngIf="dataProvider.showOverlay">
<ion-spinner name="crescent" color="tertiary"></ion-spinner>
</div>问题所在
我有一个由Wide Product Card组件显示的产品列表,我给它一个标识符输入值,作为每个产品或组件的唯一字母数字字符串。问题是,当我在ngOnInit()函数中记录ngOnInit()的值时,它返回的值类似于{'a':b},但是当我发出值this.identifier时,它将发出DOM中第一个组件的事件。就像在另一个元素下面有两个元素,如果我单击第二个元素中的event按钮。然后发射事件是第一个元素。
我试过什么
图像参考
以验证CSS没有干扰事件。
而且,由于事件是由element按钮触发的,所以事件是在正确的元素上触发的,但是事件值返回错误。
现在,在本例中,当我按选择文件按钮并选择文件时,它将返回两样东西,一个是标识符,另一个是文件对象。当我按下第二个元素上的object文件并选择一个文件时,它返回相同的标识符,但返回一个不同的文件对象。因此,每当我在产品组件文件中使用identifier函数中的值时,事件发射器就会以某种方式更改changeImage(event)变量的值。
控制台日志


发布于 2021-09-13 13:28:26
有一些错误与自定义输入文件和Ionic,你是如何隐藏真正的输入文本框?
如果您使用
<ion-item button>
<input type="file" hidden>
</ion-item>或有风格
display: none;在相同的页面角度中有一个多个实例,当单击任意按钮时,引发DOM中第一个按钮/输入的事件。
解决方法是使用css样式:
.inputfile{
opacity:0;
}在Ionic中有一些对自定义输入文件textbox的参考:如何在Ionic 2+中创建带有按钮样式的自定义文件输入?
更新示例以使工作自定义输入文件按钮具有Ionic上的事件:
<ion-button>
<input type="file" name="file" id="file" (change)="changeImage($event)" class="inputfile">
<label for="file">Choose Photo</label>
</ion-button>css类:
.inputfile {
opacity: 0;
position: absolute;
top: 0;
width: 100%;
height: 100%;
left: 0;
z-index: 999;
}这是示例
发布于 2021-09-10 11:17:13
首先,您必须将您的@Input() identifier:string="";记录在OnChanges()中,以确保每次更改时都得到它的值。
秒,您能准确地显示发出到父组件的位置吗?
https://stackoverflow.com/questions/69122495
复制相似问题