简体   繁体   English

Angular2嵌套组件和模板层次结构

[英]Angular2 nested components and template hierarchy

Iv'e recently started a new project and decided to give Angular 2 a chance. Iv'e最近开始了一个新项目,并决定给Angular 2一个机会。 As a former Backbone developer, I am now facing types of work which are really new to me. 作为一名前Backbone开发人员,我现在面临的工作类型对我来说真的很新。

I am trying to build a very simple app: I want to have a class room object, and within it a list of students. 我正在尝试构建一个非常简单的应用程序:我想要一个教室对象,并在其中包含一个学生列表。 In my point of view, each of them (classroom, student) should be different components, such that each component has it's own template. 在我看来,每个组件(教室,学生)应该是不同的组件,因此每个组件都有自己的模板。

I wish to have the templates completely separated, and on the classroom template to loop through the students and render the student template. 我希望将模板完全分开,并在教室模板上循环遍历学生并呈现学生模板。

For instance: My classroom component would like like that: import {Component, OnInit} from '@angular/core'; 例如:我的教室组件希望这样:从'@ angular / core'导入{Component,OnInit}; import {Student} from 'app/student.component'; 从“ 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() {}
}

The Classroom template would look: “课堂”模板的外观如下:

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

The Student component: 学生部分:

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() {
  }
};

And the student template, as simple as: 和学生模板一样简单:

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

But the above code shows me nothing. 但是上面的代码没有显示任何内容。 Seems like the student data is not passed to the student object. 好像学生数据没有传递到学生对象。 Iv'e seen some examples that passed the entire object down, this way: 我看到了一些通过这种方式将整个对象传递下来的示例:

[student]="student"

But it feels really wrong . 但这感觉真的不对 In Backbone for instance, I would render the parent view, and inside it append all the child views. 例如,在Backbone中,我将渲染父视图,并在其中附加所有子视图。 Here it feels odd. 在这里感觉很奇怪。

Another solution Iv'e seen is to simply add the student template to the classroom template, instead of holding them in separate files. 我见过的另一个解决方案是将学生模板简单地添加到教室模板中,而不是将它们保存在单独的文件中。 I must say that I really really don't like this practice since I believe that these components should'nt live together in the same file. 我必须说,我真的真的不喜欢这种做法,因为我认为这些组件不应该放在同一个文件中。

Another things, what doest @Input() stand for? 另一件事, @Input()代表什么? I did not really understand from the docs why @Input() gives access to data. 我不是真的从文档中了解为什么@Input()可以访问数据。

At this point I am more confused than not :] I would really appreciate some tips and your feedback and learn some good practices for dealling such tasks. 在这一点上,我比以前更困惑了:]我真的很感谢一些提示和您的反馈,并学到一些处理此类任务的良好做法。

Thanks a lot! 非常感谢!

Each instance of your <student> tag has an associated Student object that contains its data. <student>标记的每个实例都有一个关联的Student对象,该对象包含其数据。 As currently written, however, that Student object doesn't get any data from anywhere - it just sits there with empty values. 但是,按照目前的说法,该Student对象无法从任何地方获取任何数据-它只是坐在那里具有空值。 Angular does not assume anything about where you want its data to come from, there are all sorts of possibilities and it doesn't want to get in the way. Angular不假设您想要其数据来自何处,它有各种各样的可能性,并且它不会妨碍您。

So, you have to tell Angular where you want your Student objects to get their data from. 因此,您必须告诉Angular您希望Student对象从何处获取其数据。 @Input is one way to do that. @Input是执行此操作的一种方法。 When you tag a component's member variable with @Input , you are telling Angular that the value for that variable should come from the same-name property of the associated template tag. 当使用@Input标记组件的成员变量时,是在告诉Angular该变量的值应来自关联模板标记的同名属性。 If you don't specify @Input , Angular will not make any relation between the property and the variable. 如果不指定@Input ,则Angular不会在属性和变量之间建立任何关系。

Having done that, you then need to actually supply said property. 完成此操作后,您实际上需要提供上述财产。 For example, to provide the value for an @Input name , you would put [name]="someName" in the <student> tag. 例如,要提供@Input name的值,可以将[name]="someName"放在<student>标记中。

The directive *ngFor="let student of students" does not set any property. 指令*ngFor="let student of students"未设置任何属性。 It creates a variable named student that is available in that tag's scope in the template, but is not automatically used anywhere else, even in child templates. 它会创建一个名为student的变量,该变量在模板的该标记的作用域中可用,但在其他任何位置(即使在子模板中)也不会自动使用。 The snippet [student]="student" would assign that variable to the property of the same name, which the student template would then be able to use as an @Input variable. 片段[student]="student"会将变量分配给同名属性,然后学生模板就可以将其用作@Input变量。

I could be wrong, but I don't think adding [student]="student" to your code as is would actually work. 我可能是错的,但是我不认为将[student]="student"到您的代码中实际上是可行的。 Maybe Angular would recognize the matching name and replace the whole component object, but I don't think so. 也许Angular会识别出匹配的名称并替换整个组件对象,但是我不这么认为。

What you should do is separate your data and component classes. 您应该做的是将数据和组件类分开。 So you'd have Student as a data class with the fields as written but no annotation, and let's say StudentDisplay with the @Component annotation and an @Input member variable of type Student . 所以,你不得不Student与书面的领域,但没有注释的数据类,并让我们说StudentDisplay@Component注释和@Input类型的成员变量Student Then hook up that variable to a property, and write the student template in terms of that variable. 然后将该变量连接到属性,然后根据该变量编写学生模板。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM