如何访问* ngFor中定义的变量?

时间:2017-12-12 17:04:33

标签: javascript angular variables access ngfor

在我的第一个Angular 4应用程序中,我定义了一个列表组件:

<edm-document *ngFor="let document of documents" class="column is-one-quarter"></edm-document>

Document是一个界面:

export interface Document {
    id?: Number,
    name: string,
    filePath: string
}

一切都按预期工作,即我得到我的文件清单。但现在我想访问DocumentComponentedm-document标记组件)中的文档变量

在我的DocumentComponent模板中,如果我尝试这样做,则无效:

<p>{{ document.name }}</p>

我收到此错误:DocumentComponent.html:1 ERROR TypeError: Cannot read property 'name' of undefined.

我需要像这样强制执行文档定义,并将文档指定为输入:

<edm-document *ngFor="let document of documents" [document]="document" class="column is-one-quarter"></edm-document>

现在它起作用,但对我来说似乎有点多余,因为我在循环中定义了let。这是否意味着使用let定义的变量仅在设置了ngFor指令的标记中可用?

我错过了什么吗?

谢谢,

尼古拉斯

4 个答案:

答案 0 :(得分:3)

  

它有效,但对我来说似乎有点多余,因为我定义了一个let in循环

它并不像看起来那么多余,这在重写一些事情时变得很明显:

  • 如果没有明确定义组件应该使用的内容(在您的示例中使用[document]="document"),那么您的组件如何知道父变量名为document?考虑一下:

    <edm-document *ngFor="let d of documents" [document]="d"></edm-document>
    

    有人可能会争辩说Angular可以引入一些parent变量来访问外部循环变量,但是组件会知道它将如何被使用,并且只能在循环中使用。可重用的组件不应该意识到这一点。

  • 怎么知道它可以直接使用那个循环变量,而不需要一些子属性呢?像:

    <edm-document *ngFor="let d of documents" [document]="d.text"></edm-document>
    

所以:你的代码很好。

答案 1 :(得分:1)

你也可以做这样的事情

<edm-document *ngFor="let document of documents" class="column is-one-quarter">
 <span class="something">{{document.name}}</span>
</edm-document>

并在edm-document.component.html中执行类似

的操作
<ng-content select=".something"></ng-content>

答案 2 :(得分:0)

最初在DOM渲染期间,文档对象将undefined

  • 使用类型安全?运算符

    <p>{{ document?.name }}</p>
    
  • 使用具有数组长度条件的*ngIf,如下所示

    <span *ngIf="documents.length > 0"> 
       <edm-document *ngFor="let document of documents" [document]="document" 
                     class="column is-one-quarter"></edm-document>
    </span>
    

答案 3 :(得分:0)

循环的值(文档)在放置* ngFor的块内有效。在你的情况下:<edm-document>..</edm-document>

在你的例子中:

<edm-document *ngFor="let document of documents"class="column is-one-quarter">
<p>{{ document.name }}</p> <!-- document.name is valid -->
</edm-document>
<p>{{ document.name }}</p> <!-- document.name is invalid -->