【问题标题】:Angular2 nested components and template hierarchyAngular2 嵌套组件和模板层次结构
【发布时间】:2016-11-29 04:31:54
【问题描述】:

我最近开始了一个新项目,并决定给 Angular 2 一个机会。 作为一名前 Backbone 开发人员,我现在面临的工作类型对我来说非常新。

我正在尝试构建一个非常简单的应用程序:我想要一个教室对象,其中包含一个学生列表。 在我看来,它们中的每一个(教室、学生)都应该是不同的组件,因此每个组件都有自己的模板。

我希望将模板完全分离,并在教室模板上循环遍历学生并渲染学生模板。

例如: 我的课堂组件会这样: 从“@angular/core”导入 {Component, OnInit}; 从“app/student.component”导入{Student};

@Component({
  selector      :   'classroom',
  templateUrl   :   'app/classroom.component.html',
  directives    :   [Classroom]
})

export class MainContainer implements OnInit {
  students : Student[]; // assume I have an array of students here
  constructor() {}
}

课堂模板的外观:

<div>
    <student *ngFor="let student of students"></student>
</div>

学生组件:

import {Component, Input, Output} from '@angular/core';

@Component({
  selector      :   'student',
  templateUrl   :   'build/component/main-box/student.component.html'
})

export class Student {
  name : string;
  id: number;
  grade:number;
  constructor() {
  }
};

还有学生模板,就这么简单:

<div>
      name : {{name}}
      id : {{id}}
      grade : {{grade}}
</div>

但是上面的代码什么也没显示。 似乎学生数据没有传递给学生对象。 我见过一些通过这种方式传递整个对象的示例:

[student]="student"

但是感觉真的不对。例如,在 Backbone 中,我将渲染父视图,并在其中添加所有子视图。 这里感觉很奇怪。

另一个我见过的解决方案是简单地将学生模板添加到教室模板中,而不是将它们保存在单独的文件中。 我必须说我真的很不喜欢这种做法,因为我认为这些组件不应该放在同一个文件中。

另外,@Input() 代表什么?我从文档中并没有真正理解为什么 @Input() 可以访问数据。

在这一点上,我比没有更困惑 :] 我非常感谢您的一些提示和反馈,并学习一些处理此类任务的良好做法。

非常感谢!

【问题讨论】:

    标签: typescript angular


    【解决方案1】:

    &lt;student&gt; 标记的每个实例都有一个关联的 Student 对象,其中包含其数据。然而,正如目前所写的那样,Student 对象不会从任何地方获取任何数据——它只是以空值存在。 Angular 不假设您希望其数据来自何处,存在各种可能性,并且它不想妨碍您。

    因此,您必须告诉 Angular 您希望您的 Student 对象从哪里获取数据。 @Input 是一种方法。当您使用@Input 标记组件的成员变量时,您是在告诉 Angular 该变量的值应该来自关联模板标记的同名属性。如果不指定@Input,Angular 将不会在属性和变量之间建立任何关系。

    完成后,您需要实际提供所述属性。例如,要为@Input name 提供值,您可以将[name]="someName" 放在&lt;student&gt; 标记中。

    指令*ngFor="let student of students" 没有设置任何属性。它创建了一个名为student 的变量,该变量在模板中该标记的范围内可用,但不会在其他任何地方自动使用,即使在子模板中也是如此。 sn-p [student]="student" 将该变量分配给同名的属性,然后学生模板可以将其用作@Input 变量。

    我可能是错的,但我认为将[student]="student" 添加到您的代码中实际上不会起作用。也许 Angular 会识别匹配的名称并替换整个组件对象,但我不这么认为。

    你应该做的是分离你的数据和组件类。因此,您将拥有Student 作为数据类,其字段已写入但没有注释,假设StudentDisplay 带有@Component 注释和@Input 类型的Student 成员变量。然后将该变量连接到一个属性,并根据该变量编写学生模板。

    【讨论】:

    • 很好,它有效,但有没有其他方法可以做到这一点?我只是好奇
    • 谢谢你的回答,我会一直开放到明天,只是为了听听更多的意见,如果没有意见,我会批准:)
    • @superuser123 如果您将子模板内联在同一文件中而不是将其分开,则来自ngFor 指令的student 变量将在范围内,并且可以在没有属性的情况下直接使用。除此之外,我能想到的只是各种毫无意义的令人费解的方式。
    • @superuser123 您可以单独连接每个字段,使用[name]="student.name" 等,但这是无益的重复和重复。
    • 是的,这听起来有点过头了……嗯,令人惊讶的是 Angular 团队从未给予过太多关注……
    猜你喜欢
    • 2021-04-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多