【问题标题】:Property 'update' and 'quantity' doesn't exist on type '{ }'类型“{}”上不存在属性“更新”和“数量”
【发布时间】:2019-05-02 23:46:57
【问题描述】:

我正在使用 Angular 版本 6 观看 Mosh Hamedani 的教程,但问题是教程版本是 4。我正在处理 AddToCart 按钮上的电子商务项目,产品应该通过单击来增加数量按钮并使用 productId 在 Firebase 中更新,如果我尝试添加新产品,则该新产品的 id 应添加到 AngularFire 数据库中。 我在 item.update() 和 item.quantity 的最后一行有错误。请仔细阅读代码并建议我更好的解决方案。提前致谢

这里是代码。

shopping-cart.service.ts

import { Injectable } from '@angular/core';
import { AngularFireDatabase } from 'angularfire2/database';
import { Product } from '../model/product';
import { take } from 'rxjs/operators';

@Injectable({
  providedIn: 'root'
})
export class ShoppingCartService {

  constructor(private db: AngularFireDatabase, ) { }

  private create() {
   return this.db.list('/shopping-cart').push({
      dateCreated: new Date().getTime()
    })
  }

  private getCart(cartId: String) {
    return this.db.object('/shopping-cart/' + cartId);
  }

  private getItem(cartId:string, productId: String) {
   return this.db.object('/shopping-cart/' + cartId + '/items/' +productId);
  }

 private async getOrCreateCart() {
    let cartId = localStorage.getItem('cartId');

    if (cartId) return cartId;

    let result = await this.create();
    localStorage.setItem('cartId', result.key);
    return result.key;  
  }

  async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);

    item$.valueChanges().pipe(take(1)).subscribe(item => {
      // I'am getting error in update() and quantity
      item.update({ product: product,quantity: (item.quantity || 0) + 1});
    })
  }
}

预期结果是点击添加到购物车按钮后,必须在 firebase 中更新产品数量

看看我的其他文件(供参考) 1. home.component.html(这里是点击后进入.ts文件的按钮,如下图)

<div class="card-footer">
    <button (click)="addToCart(product)" style="background: #2980b9; 
             color:white" class="btn btn-block">Add to Cart
    </button>
</div>
  1. home.component.ts(此处定义的点击事件)
addToCart(product:Product) {
     this.cartService.addToCart(product);
   }

和最后一个文件 3. 购物车.service.ts

private async getOrCreateCart() {
    let cartId = localStorage.getItem('cartId');

    if (cartId) return cartId;

    let result = await this.create();
    localStorage.setItem('cartId', result.key);
    return result.key;  
  }

  async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);

    item$.valueChanges().pipe(take(1)).subscribe(item => {
      item$.update({ product: product,quantity: (item.quantity || 0) + 1});
    })
  } 

以下是错误图片: 1.错误又回来了 2.现在当我修改上面的addToCart(product:Product)代码时:

async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);

    item$.snapshotChanges().pipe(take(1)).subscribe((item: any) => {
      if(item.key != null) {
        item$.update({ product: product,quantity: (item.quantity || 0) + 1});
      } else {
        item$.set( {product:product, quantity:1});
     }   
    });
  }

我收到以下错误:

这就是我所拥有的...请再次查看错误并提出更好的解决方案...提前致谢

【问题讨论】:

  • 感谢您的信息。您在点击事件中使用的product 变量在哪里定义?
  • 你的代码在 GitHub 上吗?如果您可以共享整个代码,这将更简单。
  • product 变量属于 Product 接口模型,该模型在组件的 addToCart(product:Product) 方法中作为参数传递....对于您的第二个问题...不,我没有上传Github上的项目由于错误,一旦错误消失,我会上传它
  • GitHub 旨在用于软件开发,而不仅仅是用于存储完成的代码;)。如果我只看到您的部分代码,我很难提供帮助。但我认为这个product 变量出了点问题。这应该是您以某种方式从数据库中加载的实际产品。
  • 好的,我会尽快上传到 Github 上

标签: javascript firebase firebase-realtime-database angular6 angularfire


【解决方案1】:

您对从数据库中获得的值使用更新方法。您必须对数据库对象使用更新方法。

https://github.com/angular/angularfire2/blob/master/docs/rtdb/objects.md

我无法测试它,如果它有效,请告诉我。

async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let itemRef = this.getItem(cartId, product.key);

    itemRef.valueChanges().pipe(take(1)).subscribe(item => {
      itemRef.update({ product: product,quantity: (item.quantity || 0) + 1});
    })
 }

【讨论】:

  • 哇太棒了... update() 错误消失了,但是,'item.quantity' 中的数量仍然存在... 错误相同 '{}' 类型上不存在属性数量.. . 但是,项目仍然编译成功。现在的问题是 TypeError: Cannot read property 'key' of undefined... 当点击 Add To Cart 时
  • 好的,我想我已经找到了您教程的源代码。我相信它应该是 product.$key 而不是 product.key。我已经编辑了答案。
  • 感谢您的回复...在 Angular 6 中,$key 被替换为仅在 Angular 4 中的键...嗯,问题是它无法通过产品从 firebase 获取值型号
  • 这里是我的产品型号供大家参考导出接口Product { key: string;标题:字符串;价格:数量;类别:字符串;图片网址:字符串; }
  • 我看到你改变了一些教程代码。我认为问题可能出在模型文件夹中的 shopping-cart-item.ts 中。在原始代码中没有产品属性。您是否在那里更改了某些内容并忘记添加数量属性?
【解决方案2】:

您的 products.component.ts 文件是这样的吗?

products.component.ts

import { ShoppingCartService } from './../shopping-cart.service';
import { Product } from './../models/product';
import { ActivatedRoute } from '@angular/router';

import { ProductService } from './../product.service';
import { Component, OnInit, OnDestroy } from '@angular/core';
import { switchMap } from 'rxjs/operators';
import { Subscription } from 'rxjs';
@Component({
    selector: 'app-products',
    templateUrl: './products.component.html',
    styleUrls: [ './products.component.css' ]
})
export class ProductsComponent implements OnInit, OnDestroy {
    products: Product[] = [];
    filteredProducts: Product[] = [];
    category: string;
    cart: any;
    subscription: Subscription;
    constructor(
        route: ActivatedRoute,
        productService: ProductService,
        private shoppingCartService: ShoppingCartService
    ) 
    {
        productService
            .getAll()
            .pipe(
                switchMap((products: Product[]) => {
                    this.products = products;
                    return route.queryParamMap;
                })
            )
            .subscribe((params) => {
                this.category = params.get('category');

                this.filteredProducts = this.category
                    ? this.products.filter((p) => p.category === this.category)
                    : this.products;
            });
    }

    async ngOnInit() {
        this.subscription = (await this.shoppingCartService.getCart())
            .valueChanges()
            .subscribe((cart) => (this.cart = cart));
    }
    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

这里看看 ngOnInit() 函数。 在 .subscribe() 之前你必须写 .valueChanges()

这意味着你必须写

async ngOnInit() {
    this.subscription = (await this.shoppingCartService.getCart())
        .valueChanges()
        .subscribe((cart) => (this.cart = cart));
}

shopping-cart.service.ts

async addToCart(product: Product) {
    let cartId = await this.getOrCreateCart();
    let item$ = this.getItem(cartId, product.key);
    item$.snapshotChanges().pipe(take(1)).subscribe((item) => {
        if (item.payload.exists()) {
            item$.update({ quantity: item.payload.exportVal().quantity + 1 });
        } else {
            item$.set({ product: product, quantity: 1 });
        }
    });
}

我认为它会起作用。请告诉我它是否有效。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-03-19
    • 1970-01-01
    • 2021-01-09
    • 2020-08-02
    • 2021-05-01
    • 2021-07-10
    相关资源
    最近更新 更多