簡體   English   中英

我想編輯我的產品列表時遇到問題,出現此錯誤無法讀取null的屬性“ title”

[英]I have an issue when I want to edit my product list and i am getting this error Cannot read property 'title' of null

我的數據存儲在db中后出現問題,我想對其進行編輯。 它沒有顯示數據,我無法讀取屬性錯誤。

HTML

admin-products.component.html

<p>
  <a routerLink="/admin/products/new" class="btn btn-primary">New Products</a>
</p>
<table class="table">
  <thead>
    <tr>
      <th>Title</th>
      <th>Price</th>
      <th></th>
    </tr>
  </thead>
  <tbody>
    <tr *ngFor="let p of products$ | async">
      <td>{{ p.title }}</td>
      <td>{{ p.price }}</td>
      <td><a [routerLink]="['/admin/products/', p.$key]">Edit</a></td>
    </tr>
  </tbody>
</table>

product-form.component.html

如果我在控制台中檢查錯誤鏈接,則所有輸入字段均顯示錯誤。 我認為大多數錯誤可能在這里?

    <div class="row">
  <div class="col-md-6">
    <form #f="ngForm" (ngSubmit)="save(f.value)">
      <div class="form-group">
        <label for="title">Title</label>
        <input
          #title="ngModel"
          [(ngModel)]="product.title"
          name="title"
          id="title"
          type="text"
          class="form-control"
          required
        />
        <div class="alert alert-danger" *ngIf="title.touched && title.invalid">
          Title is required.
        </div>
      </div>
      <div class="form-group">
        <label for="price">Price</label>
        <div class="input-group-prepend">
          <span class="input-group-text"> $ </span>
          <input
            #price="ngModel"
            [(ngModel)]="product.price"
            name="price"
            id="price"
            type="number"
            class="form-control"
            required
            [min]="0"
          />
        </div>
        <div class="alert alert-danger" *ngIf="price.touched && price.invalid">
          <div *ngIf="price.errors.required">Price is required.</div>
          <div *ngIf="price.errors.min">Price should be 0 or higher.</div>
        </div>
      </div>
      <div class="form-group">
        <label for="category">Category</label>
        <select
          #category="ngModel"
          [(ngModel)]="product.category"
          name="category"
          id="category"
          class="form-control"
          required
        >
          <option value=""></option>
          <option *ngFor="let c of categories$ | async" [value]="c.$key">
            {{ c.name }}
          </option>
        </select>
        <div
          class="alert alert-danger"
          *ngIf="category.touched && category.invalid"
        >
          Category is required
        </div>
      </div>
      <div class="form-group">
        <label for="imageUrl">Image Url</label>
        <input
          #imageUrl="ngModel"
          [(ngModel)]="product.imageUrl"
          name="imageUrl"
          id="imageUrl"
          type="text"
          class="form-control"
          required
          url
        />
        <div
          class="alert alert-danger"
          *ngIf="imageUrl.touched && imageUrl.invalid"
        >
          <div *ngIf="imageUrl.errors.required">Image is required</div>
          <div *ngIf="imageUrl.errors.url">Please enter a vaild URL</div>
        </div>
      </div>
      <button class="btn btn-primary">Save</button>
    </form>
  </div>
  <div class="col-md-6">
    <div class="card" style="width: 18rem;">
      <img
        class="card-img-top"
        [src]="product.imageUrl"
        *ngIf="product.imageUrl"
      />
      <div class="card-body">
        <h5 class="card-title">{{ product.title }}</h5>
        <p class="card-text">{{ product.price | currency: 'USD':true }}</p>
      </div>
    </div>
  </div>
</div>

產品表格。組件

    import { Component } from '@angular/core';
import { CategoryService } from 'src/app/category.service';
import { ProductService } from 'src/app/product.service';
import { Router, ActivatedRoute } from '@angular/router';
import 'rxjs/add/operator/take';

@Component({
  selector: 'app-product-form',
  templateUrl: './product-form.component.html',
  styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent {
  categories$;
  product = {};

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private categoryService: CategoryService,
    private productService: ProductService
  ) {
    this.categories$ = categoryService.getCategories();

    // tslint:disable-next-line:prefer-const
    let id = this.route.snapshot.paramMap.get('id');
    // tslint:disable-next-line:curly
    if (id)
      this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));
  }

  save(product) {
    this.productService.create(product);
    this.router.navigate(['/admin/products']);
  }
}

產品服務

import { Injectable } from '@angular/core';
import { AngularFireDatabase, AngularFireList } from 'angularfire2/database';
@Injectable()
export class ProductService {
  products$: AngularFireList<any[]>;
  constructor(private db: AngularFireDatabase) {
    this.products$ = this.db.list('/products');
  }
  create(product) {
    return this.products$.push(product);
  }

  getAll() {
    return this.db.list('/products').valueChanges();
  }

  get(productId) {
    return this.db.object('/products/' + productId);
  }
}

我通過使用* ngIf,[ngModel] =“ product?.title”嘗試了此方法

<input *ngIf="title">

您是否嘗試過用ng-container包裝表格?

產品表格。組件

@Component({
  selector: 'app-product-form',
  templateUrl: './product-form.component.html',
  styleUrls: ['./product-form.component.css']
})
export class ProductFormComponent {
  categories$;
  product = null;

  constructor(
    private router: Router,
    private route: ActivatedRoute,
    private categoryService: CategoryService,
    private productService: ProductService
  ) {
    this.categories$ = categoryService.getCategories();

    // tslint:disable-next-line:prefer-const
    let id = this.route.snapshot.paramMap.get('id');
    // tslint:disable-next-line:curly
    if (id)
      this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));
  }

  save(product) {
    this.productService.create(product);
    this.router.navigate(['/admin/products']);
  }
}

product-form.component.html

<div class="row">
  <div class="col-md-6">
    <ng-container *ngIf="product">
       <form #f="ngForm" (ngSubmit)="save(f.value)">
       <!-- YOUR CODE -->
       </form>
    </ng-container>
  </div>
</div>

嘗試這個,

export class ProductFormComponent {
  categories$;
  product = {
               "title": '',
               "price": '', 
               "category": '',
               "imageUrl": '',                
            };



constructor(
        private router: Router,
        private route: ActivatedRoute,
        private categoryService: CategoryService,
        private productService: ProductService
      ) {
        this.categories$ = categoryService.getCategories();

        // tslint:disable-next-line:prefer-const
        let id = this.route.snapshot.paramMap.get('id');
        // tslint:disable-next-line:curly
        if (id)
          this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));
      }

      save(product) {
        this.productService.create(product);
        this.router.navigate(['/admin/products']);
      }
    }

之所以失敗,是因為

this.productService.get(id).valueChanges().take(1).subscribe(p => (this.product = p));

上一行需要花費一些時間才能從Firebase獲得響應,與此同時,HTML組件將在此之前呈現,因此,由於沒有標題,價格,類別,因此它試圖訪問HTML組件中的產品對象,產品對象中的imageUrl會導致錯誤。 因此,分配空值,稍后在收到響應后將其更新

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM