Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
348 views
in Technique[技术] by (71.8m points)

html - 角度ngFor绑定错误。 为什么会出现错误?(Angular ngFor binding error. Why am I getting an error?)

I've got a main component called DOCUMENT.

(我有一个名为DOCUMENT的主要组件。)

This document takes a URL segment and fetches an array of associated objects from my database.

(该文档采用一个URL段,并从我的数据库中获取一个关联对象的数组。)

Then, using @Output() documents = new EventEmitter() and an @Input() in a DOCUMENT VIEW component, I then iterate of the incoming array with *ngFor .

(然后,在DOCUMENT VIEW组件中使用@Output() documents = new EventEmitter()@Input() ,然后使用*ngFor迭代传入的数组。)

The whole thing works and the elements are displayed, but I keep getting the error

(整个工作正常并且显示了元素,但是我不断收到错误消息)

Error: Cannot find a differ supporting object '[object Object]' of type 'object'.

(错误:找不到类型为“对象”的其他支持对象“ [对象对象]”。)

NgFor only supports binding to Iterables such as Arrays.

(NgFor仅支持绑定到Iterables,例如数组。)

I'm stumped.

(我很沮丧)

It feels like a typescript type error for some reason.

(由于某种原因,感觉像是打字稿类型错误。)

I actually console.log the initial database return and indeed, it's an array of objects.

(我实际上是console.log初始数据库返回,实际上,它是一个对象数组。)

So, unsure where this error is coming from

(因此,不确定此错误来自何处)

----------TS----------

(---------- TS ----------)

import { Component, OnInit, Output, EventEmitter } from "@angular/core";
import { DocumentService } from "src/app/services/document.service";
import { ActivatedRoute, Router, NavigationEnd } from "@angular/router";

@Component({
  selector: "app-documents",
  templateUrl: "./documents.component.html",
  styleUrls: ["./documents.component.css"]
})
export class DocumentsComponent implements OnInit {
  @Output() documents = new EventEmitter();
  department;
  navigationSubscription;

  constructor(
    private _documentService: DocumentService,
    private _route: ActivatedRoute,
    private _router: Router
  ) {
    // subscribe to the router events - storing the subscription so
    // we can unsubscribe later.
    this.navigationSubscription = this._router.events.subscribe((e: any) => {
      // If it is a NavigationEnd event re-initalise the component
      if (e instanceof NavigationEnd) {
        this.initialiseComponent();
      }
    });
  }

  initialiseComponent() {
    this.getDocuments();
  }
  ngOnDestroy() {
    // avoid memory leaks here by cleaning up after ourselves. If we
    // don't then we will continue to run our initialiseInvites()
    // method on every navigationEnd event.
    if (this.navigationSubscription) {
      this.navigationSubscription.unsubscribe();
    }
  }

  ngOnInit() {
    this.getDocuments();
  }

  getDocuments() {
    this._route.paramMap.subscribe(params => {
      this.department = params.get("department");
    });

    this._documentService
      .getDocumentsByDepartment(this.department)
      .subscribe(response => {
        this.documents = response["documents"];
        console.log(response["documents"]);
      });
  }
}

--------- SAME COMPONENT HTML -----------

(---------相同的HTML HTML -----------)

<app-documents-view [docs]="documents"></app-documents-view>

------------ VIEW COMPONENT TS ------------

(------------查看组件TS ------------)

import { Component, OnInit, Input } from "@angular/core";
import { DocumentService } from "src/app/services/document.service";
import { saveAs } from "file-saver";
import { faEye, faDownload } from "@fortawesome/free-solid-svg-icons";

@Component({
  selector: "app-documents-view",
  templateUrl: "./documents-view.component.html",
  styleUrls: ["./documents-view.component.css"]
})
export class DocumentsViewComponent implements OnInit {
  // ICONS
  faEye = faEye;
  faDownload = faDownload;

  @Input() docs; // loaded with documents from parent component (@Output())
  showDocumentListing = true;
  showFileViewer = false;
  fileUrl; // Used to set the view document viwer (ngx-viewer)

  constructor(private _documentService: DocumentService) {}

  ngOnInit() {}

  viewDocument(id) {
    this._documentService.getDocument(id).subscribe(response => {
      this.fileUrl = response["documentUrl"];
      this.showDocumentListing = false;
      this.showFileViewer = true;
    });
  }

  downloadDocument(id) {
    this._documentService.getDocument(id).subscribe(response => {
      saveAs(response["documentUrl"], response["documentKey"]);
    });
  }

  closeDocumentView() {
    this.showFileViewer = false;
    this.showDocumentListing = true;
  }
}

---------- VIEW COMPONENT HTML ------------

(----------查看组件HTML ------------)

<div class="card" *ngIf="docs && showDocumentListing">
  <div class="card-header bg-light text-primary">
    <h3>Documents</h3>
  </div>
  <div class="card-body border border-light">
    <div class="table-responsive mt-3">
      <table class="table">
        <thead>
          <th>Filename</th>
          <th>Description</th>
          <th>Action</th>
        </thead>
        <tbody>
          <tr *ngFor="let doc of docs">
            <td>{{ doc?.key }}</td>
            <td>{{ doc?.description }}</td>
            <td>
              <button class="btn btn-primary mr-1" (click)="viewDocument(doc._id)">
                <fa-icon [icon]="faEye"></fa-icon>
              </button>
              <button class="btn btn-primary" (click)="downloadDocument(doc._id)">
                <fa-icon [icon]="faDownload"></fa-icon>
              </button>
            </td>
          </tr>
        </tbody>
      </table>
    </div>
  </div>
</div>

  ask by mike varela translate from so

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

Your problem is to assign the response["documents"] to an @Output it's wrong.Here you do not need @Output , you should assign the the retrieved document to the documents then send to the app-documents-view as a porp .

(您的问题是将response["documents"]分配给@Output错误的。这里不需要@Output ,应该将检索到的documents分配给文档,然后以porp的形式发送到app-documents-view 。)

In your DocumentsComponent remove the following line

(在您的DocumentsComponent删除以下行)

@Output() documents = new EventEmitter();

and use this

(并使用这个)

public document: any;

instead.

(代替。)


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...