您能够经过将HTML模板中的控件绑定到Angular组件的属性来显示数据。
在这个页面中,您将建立一个包含英雄列表的组件。 您将显示英雄名单的列表,并有条件地在列表下方显示一条消息。
最终的用户界面以下所示:css
显示组件属性的最简单方法是经过插值来绑定属性名称。 使用插值,能够将属性名称放在视图模板中,并用双花括号括起来:{{myHero}}。java
按照设置说明建立名为displays_data的新项目。git
而后经过更改模板和组件的主体来修改app_component.dart文件。github
当你完成后,它应该是这样的:lib/app_component.dartweb
import 'package:angular/angular.dart'; @Component( selector: 'my-app', template: ''' <h1>{{title}}</h1> <h2>My favorite hero is: {{myHero}}</h2> ''', ) class AppComponent { final title = 'Tour of Heroes'; String myHero = 'Windstorm'; }
您向之前的空组件添加了两个属性:title和myHero。express
修改后的模板使用双重大括号插值显示两个组件属性:bootstrap
template: ''' <h1>{{title}}</h1> <h2>My favorite hero is: {{myHero}}</h2> ''',
Angular会自动从组件中抽取title和myHero属性的值,并将这些值插入到浏览器中。 当这些属性改变时,Angular会更新显示。api
更准确地说,从新显示是在与视图相关的某种异步事件以后发生的,例如按键,计时器完成或对HTTP请求的响应。浏览器
请注意,您不要调用new来建立AppComponent类的实例。 Angular正在为你建立一个实例。 怎样建立的?
@Component注解中的CSS选择器指定了一个名为<my-app>的元素。 该元素是index.html文件正文中的占位符:web/index.html (body)
<body> <my-app>Loading...</my-app> </body>
当您使用AppComponent类(在web / main.dart中)引导时,Angular将在index.html中查找<my-app>,查找它,实例化AppComponent的一个实例,并将其呈如今<my-app> 标签。
如今运行应用程序。 它应该显示标题和英雄的名字:
您能够将组件的模板存储在两个地方之一中。 您可使用模板属性内联定义它,也可使用组件元数据@Component注解的templateUrl属性连接到单独定义模板的HTML文件。
内嵌和单独的HTML之间的选择是一个品味,环境和组织政策的问题。 这里的应用程序使用内联的HTML,由于模板很小,演示更简单,没有额外的HTML文件。
在任一种样式中,模板数据绑定都具备对组件属性的相同访问权限。
要显示英雄列表,首先向组件添加英雄名字列表,并将myHero从新定义为列表中的第一个名字。
lib/app_component.dart (class)
class AppComponent { final title = 'Tour of Heroes'; List<String> heroes = [ 'Windstorm', 'Bombasto', 'Magneta', 'Tornado', ]; String get myHero => heroes.first; }
如今使用模板中的Angular ngFor指令来显示英雄列表中的每一个项目。lib/app_component.dart (template)
template: ''' <h1>{{title}}</h1> <h2>My favorite hero is: {{myHero}}</h2> <p>Heroes:</p> <ul> <li *ngFor="let hero of heroes"> {{ hero }} </li> </ul> ''',
此UI使用带有<ul>和<li>标签的HTML无序列表。 <li>元素中的* ngFor是Angular“repeater”指令。 它将<li>元素(及其子元素)标记为“repeater模板”:
<li *ngFor="let hero of heroes"> {{ hero }} </li>
不要忘记* ngFor中的主要星号(*)。 这是语法的重要组成部分。 有关更多信息,请参阅模板语法页面。
注意ngFor指令中的hero变量; 它是模板输入变量的一个例子。 在“模板语法”页面的microsyntax部分阅读有关模板输入变量的更多信息。
Angular为列表中的每一个项目复制<li>,将hero变量设置为当前迭代中的项目(英雄)。 Angular使用该变量做为双曲花括号内插的上下文。
在这种状况下,ngFor正在显示一个列表,但ngFor能够为任何Iterable对象重复项目。
@Component(directives:...)
在模板中使用任何Angular指令以前,您须要将它们列在组件的@Component注解的指令参数中。 您能够单独列出指令,或者为了方便起见,您可使用像CORE_DIRECTIVES这样的组:lib/app_component.dart (directives)
import 'package:angular/angular.dart'; @Component( selector: 'my-app', // ··· directives: const [CORE_DIRECTIVES], )
刷新浏览器。 如今英雄出如今一个无序的列表中。
应用程序的代码直接在组件内定义数据,这不是最佳实践。 可是,在一个简单的演示中,不要紧。
目前,绑定是一个字符串列表。 在实际应用中,大多数绑定是针对更专业化的对象。
要将此绑定转换为使用专用对象,请将英雄名称列表转换为Hero对象列表。 为此,你须要一个Hero类。
使用下面的代码在名为lib的文件夹中建立一个hero.dart新文件:lib/src/hero.dart
class Hero { final int id; String name; Hero(this.id, this.name); @override String toString() => '$id: $name'; }
您已经使用构造函数,两个属性(id和name)和toString()方法定义了一个类。
导入Hero类后,AppComponent.heroes属性能够返回一个Hero对象的类型列表:lib/app_component.dart (heroes)
List<Hero> heroes = [ new Hero(1, 'Windstorm'), new Hero(13, 'Bombasto'), new Hero(15, 'Magneta'), new Hero(20, 'Tornado') ]; Hero get myHero => heroes.first;
接下来,更新模板。 此刻它显示英雄的id和name。修正这个问题,只显示英雄的name属性。
lib/app_component.dart (template)
template: ''' <h1>{{title}}</h1> <h2>My favorite hero is: {{myHero.name}}</h2> <p>Heroes:</p> <ul> <li *ngFor="let hero of heroes"> {{ hero.name }} </li> </ul> ''',
显示看起来同样,但代码更清晰。
有时候,只有在特定状况下,应用程序才须要显示视图或视图的一部分。
若是有三个以上的英雄,让咱们更改示例以显示一条消息。
Angular ngIf指令根据布尔条件插入或删除一个元素。 要看到它的实际操做,请在模板的底部添加如下段落:lib/app_component.dart (message)
<p *ngIf="heroes.length > 3">There are many heroes!</p>
不要忘记* ngIf中的星号(*)。 这是语法的重要组成部分。 在“模板语法”页面的ngIf部分阅读有关ngIf和*的更多信息。
双引号内的模板表达式,* ngIf =“heros.length> 3”,看上去和表现很像Dart。 当组件的英雄列表中有三个以上的项目时,Angular会将该段落添加到DOM,并显示消息。 若是有三个或更少的项目,Angular会忽略该段落,因此不会显示任何消息。 有关更多信息,请参阅模板语法页面的模板表达式部分。
Angular没有显示和隐藏消息。 它正在添加和删除DOM中的段落元素。 这能够提升性能,特别是在大型项目中,当有条件地包含或排除大量的HTML与许多数据绑定。
试试看。 因为列表中有四个项目,因此应该显示消息。 回到app_component.dart并删除或注释掉英雄列表中的一个元素。 浏览器应该自动刷新,消息应该消失。
如今你知道如何使用:
这是最后的代码:
lib/app_component.dart (heroes)
import 'package:angular/angular.dart'; import 'src/hero.dart'; @Component( selector: 'my-app', template: ''' <h1>{{title}}</h1> <h2>My favorite hero is: {{myHero.name}}</h2> <p>Heroes:</p> <ul> <li *ngFor="let hero of heroes"> {{ hero.name }} </li> </ul> <p *ngIf="heroes.length > 3">There are many heroes!</p> ''', directives: const [CORE_DIRECTIVES], ) class AppComponent { final title = 'Tour of Heroes'; List<Hero> heroes = [ new Hero(1, 'Windstorm'), new Hero(13, 'Bombasto'), new Hero(15, 'Magneta'), new Hero(20, 'Tornado') ]; Hero get myHero => heroes.first; }
lib/src/hero.dart
class Hero { final int id; String name; Hero(this.id, this.name); @override String toString() => '$id: $name'; }
web/main.dart
import 'package:angular/angular.dart'; import 'package:displaying_data/app_component.dart'; void main() { bootstrap(AppComponent); }
web/index.html
<!DOCTYPE html> <html> <head> <script> // WARNING: DO NOT set the <base href> like this in production! // Details: https://webdev.dartlang.org/angular/guide/router (function () { var m = document.location.pathname.match(/^(\/[-\w]+)+\/web($|\/)/); document.write('<base href="' + (m ? m[0] : '/') + '" />'); }()); </script> <title>Displaying Data</title> <link rel="stylesheet" href="styles.css"> <link rel="icon" type="image/png" href="favicon.png"> <script defer src="main.dart" type="application/dart"></script> <script defer src="packages/browser/dart.js"></script> </head> <body> <my-app>Loading...</my-app> </body> </html>
pubspec.yaml
name: displaying_data description: Displaying Data version: 0.0.1 environment: sdk: '>=1.24.0 <2.0.0' dependencies: angular: ^4.0.0 dev_dependencies: browser: ^0.10.0 dart_to_js_script_rewriter: ^1.0.1 transformers: - angular: entry_points: web/main.dart - dart_to_js_script_rewriter