前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >专栏 >AngularDart4.0 英雄之旅-教程-04明细 顶

AngularDart4.0 英雄之旅-教程-04明细 顶

作者头像
南郭先生
发布于 2018-08-14 07:28:39
发布于 2018-08-14 07:28:39
3K00
代码可运行
举报
文章被收录于专栏:Google DartGoogle Dart
运行总次数:0
代码可运行

在此页面中,您将扩展“Tour of Heroes”应用程序,以显示英雄列表,并允许用户选择英雄并显示英雄的详细信息。

完成此页面后,该应用应该看起来像这个实例(查看源代码)。

必备条件

在继续本“英雄之旅”页面之前,请确认您在“英雄编辑器”页面之后具有以下结构。 如果您的结构不匹配,请返回该页面以弄清楚您错过了什么。

如果该应用尚未运行,请启动该应用。 当您进行更改时,请通过重新加载浏览器窗口来保持运行

应用程序重构

在添加新功能之前,您可以从应用程序重构中受益。

应用模板文件

您将对应用程序组件的模板进行多次更新。 首先,将模板移动到自己的文件中:

lib/app_component.html

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<h1>{{title}}</h1>
<h2>{{hero.name}} details!</h2>
<div><label>id: </label>{{hero.id}}</div>
<div>
  <label>name: </label>
  <input [(ngModel)]="hero.name" placeholder="name">
</div>

用指向新模板文件的templateUrl替换@Component模板:

lib/app_component.dart (metadata)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component(
  selector: 'my-app',
  templateUrl: 'app_component.html',
  directives: const [formDirectives],
)

刷新浏览器。 该应用仍然继续运行。

Hero类

 分开使用并将Hero类从app_component.dart 中移动到它自己的文件中,创建lib/src文件夹来装Hero源文件:lib/src/hero.dart

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
class Hero {
  final int id;
  String name;

  Hero(this.id, this.name);
}

回到应用程序组件中,使用相对路径添加一个import 到新创建的文件:lib/app_component.dart (hero import)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'src/hero.dart';

刷新浏览器,程序将正常运行,现在添加新功能的准备工作就做好了。

展示英雄们

    显示一个英雄列表,首先需要将英雄们添加到视图模板

模拟英雄

    在lib / src下的以下文件中创建十个英雄的列表:lib/src/mock_heroes.dart

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'hero.dart';

final mockHeroes = <Hero>[
  new Hero(11, 'Mr. Nice'),
  new Hero(12, 'Narco'),
  new Hero(13, 'Bombasto'),
  new Hero(14, 'Celeritas'),
  new Hero(15, 'Magneta'),
  new Hero(16, 'RubberMan'),
  new Hero(17, 'Dynama'),
  new Hero(18, 'Dr IQ'),
  new Hero(19, 'Magma'),
  new Hero(20, 'Tornado')
];

最终这个应用程序将从Web服务获取英雄列表,但现在你可以显示模拟英雄。

应用hero字段

将hero字段替换为AppComponent中的公共heros字段,并使用模拟英雄进行初始化(不要忘记导入):lib/app_component.dart (heroes)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import 'src/mock_heroes.dart';

// ···
class AppComponent {
  final title = 'Tour of Heroes';
  List<Hero> heroes = mockHeroes;
  // ···
}

英雄数据与类实现分开,因为英雄名字最终将来自数据服务

 在模板中显示英雄名称

 要在无序列表中显示英雄名称,请将所有当前模板替换为以下HTML:lib/app_component.html (heroes template)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<h1>{{title}}</h1>
<h2>My Heroes</h2>
<ul class="heroes">
  <li>
    <!-- each hero goes here -->
  </li>
</ul>

下一步你将添加英雄名字

使用ngFor指令罗列英雄

目标是将组件中的英雄列表绑定到模板,迭代它们,并单独显示它们。通过添加核心指令* ngFor修改<li>标签。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<li *ngFor="let hero of heroes">

ngFor的前缀(*)是此语法的关键部分。 它表示<li>元素及其子元素构成一个主模板。 ngFor指令遍历组件的英雄列表并为该列表中的每个英雄呈现该模板的一个实例。 表达式部分将hero标识为模板输入变量,其中包含每个迭代的英雄详情。 你可以在模板中引用这个变量来访问当前英雄的属性。 在显示数据Showing a list property with *ngFor部分阅读更多关于ngFor和模板输入变量和模板语法页的ngFor部分

在<li>节点内添加内容hero模板变量来显示英雄属性 lib/app_component.html (ngFor)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<li *ngFor="let hero of heroes">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>

要在模板中使用Angular指令,需要在组件的@Component注解的指令参数中列出。 与您在第1部分中所做的相似,添加所有:CORE_DIRECTIVES:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
CORE_DIRECTIVES = const [NgClass, NgFor, NgIf, NgTemplateOutlet, NgStyle, NgSwitch, NgSwitchWhen, NgSwitchDefault]

lib/app_component.dart (directives)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component(
  selector: 'my-app',
  // ···
  directives: const [CORE_DIRECTIVES, formDirectives],
)

刷新浏览器,英雄列表将显示出来。

装饰英雄

用户应该得到一个他们徘徊和被选中英雄的视觉提示。要为组件添加样式,可以设置@Component注解的styles参数:lib/app_component.dart (styles)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// Not recommended when adding many CSS classes:
styles: const [
  '''
    .selected { ... }
    .heroes { ... }
    ...
  '''
],

但是,当添加多个样式时,这使得Dart文件更长,更不易读。 而应将样式放在.css文件中,并使用@Component的styleUrls参数引用该文件。 按照惯例,组件的CSS和Dart文件的名称具有相同的基础命名前缀(app_component)。lib/app_component.dart (stylUrls)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
@Component(
  selector: 'my-app',
  // ···
  styleUrls: const ['app_component.css'],
  // ···
)

lib/app_component.css

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
.selected {
  background-color: #CFD8DC !important;
  color: white;
}
.heroes {
  margin: 0 0 2em 0;
  list-style-type: none;
  padding: 0;
  width: 15em;
}
.heroes li {
  cursor: pointer;
  position: relative;
  left: 0;
  background-color: #EEE;
  margin: .5em;
  padding: .3em 0;
  height: 1.6em;
  border-radius: 4px;
}
.heroes li.selected:hover {
  color: white;
}
.heroes li:hover {
  color: #607D8B;
  background-color: #EEE;
  left: .1em;
}
.heroes .text {
  position: relative;
  top: -3px;
}
.heroes .badge {
  display: inline-block;
  font-size: small;
  color: white;
  padding: 0.8em 0.7em 0 0.7em;
  background-color: #607D8B;
  line-height: 1em;
  position: relative;
  left: -1px;
  top: -4px;
  height: 1.8em;
  margin-right: .8em;
  border-radius: 4px 0 0 4px;
}

将样式分配给组件时,它们的作用域为该特定组件。 这些样式仅适用于AppComponent,不影响外部HTML。

显示英雄的模板应该是这样的:lib/app_component.html (styled heroes)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<h2>My Heroes</h2>
<ul class="heroes">
  <li *ngFor="let hero of heroes">
    <span class="badge">{{hero.id}}</span> {{hero.name}}
  </li>
</ul>

选择一个英雄

该应用程序现在显示英雄列表,以及在详细信息视图中的单个英雄。 但是列表和细节视图没有连接。 当用户从列表中选择一个英雄时,选择的英雄应该出现在细节视图中。 这个UI模式被称为“主/细节”。在这种情况下,主人是英雄列表,细节是选择的英雄。

接下来,您将通过selectedHero组件属性将主链接到详细信息,该属性绑定到单击事件。

处理点击事件

添加点击事件绑定到<li>:lib/app_component.html (click)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<li *ngFor="let hero of heroes" (click)="onSelect(hero)">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>

圆括号将<li>元素的点击事件标识为目标。 onSelect(hero)表达式调用AppComponent方法onSelect(),传递模板输入变量hero作为参数。 这是你在ngFor指令中定义的同一个英雄变量。

用户输入页面和模板语法页面的事件绑定部分了解有关事件绑定的更多信息。

添加一个点击处理程序来显示选定的英雄 

你不再需要hero属性,因为你不再显示一个英雄; 你正在显示一个英雄列表。 但是用户可以通过点击选择一个英雄。 所以用这个简单的selectedHero属性来替换hero属性:lib/app_component.dart (selectedHero)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Hero selectedHero;

在用户选择英雄之前,所有的英雄名字都应该被取消选择,所以你不会像hero一样初始化selectedHero。添加一个onSelect()方法,将selectedHero属性设置为用户单击的英雄。lib/app_component.dart (onSelect)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
void onSelect(Hero hero) => selectedHero = hero;

该模板仍然是指旧的英雄属性。 绑定到新的selectedHero属性,如下所示:lib/app_component.html (selectedHero details)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<h2>{{selectedHero.name}} details!</h2>
<div><label>id: </label>{{selectedHero.id}}</div>
<div>
  <label>name: </label>
  <input [(ngModel)]="selectedHero.name" placeholder="name">
</div>

使用ngIf指令隐藏空的对象

当应用程序加载时,selectedHero为null。 当用户点击英雄的名字时,所选择的英雄被初始化。 Angular无法显示null selectedHero的属性并抛出以下错误,在浏览器的控制台中可见:

EXCEPTION: TypeError: Cannot read property 'name' of undefined in [null]

尽管selectedHero.name显示在模板中,但必须保留DOM外的英雄详细信息,直到出现选定的英雄。用<div>包装模板的HTML英雄细节内容。 然后添加ngIf核心指令并将其设置为selectedHero!= null。lib/app_component.html (ngIf)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<div *ngIf="selectedHero != null">
  <h2>{{selectedHero.name}} details!</h2>
  <div><label>id: </label>{{selectedHero.id}}</div>
  <div>
    <label>name: </label>
    <input [(ngModel)]="selectedHero.name" placeholder="name">
  </div>
</div>

不要忘记ngIf前面的星号(*)。

刷新浏览器,该应用程序不再失败,名称列表再次显示在浏览器中。

当没有选定的英雄时,ngIf指令从DOM中移除英雄详情HTML。 没有英雄细节元素或绑定担心。

当用户选择一个英雄时,selectedHero变为非null,ngIf将英雄详细内容放入DOM中,并评估嵌套的绑定。

结构指令页面和模板语法页面的内置指令部分阅读有关ngIf和ngFor的更多信息。

格式化选中hero

当选择的英雄细节显示在列表下方时,很难在列表中识别选定的英雄。

在上面添加的样式元数据中,有一个名为selected的自定义CSS类。 为了让选定的英雄更清晰可见,当用户点击英雄名字时,你将把这个选定的class应用到<li>。 例如,当用户点击“Magneta”时,它应该用一个独特但微妙的背景颜色渲染,如下所示:

在模板中,将以下绑定添加到<li>标记中:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[class.selected]="hero === selectedHero"

当表达式(hero === selectedHero)为true时,Angular将添加所选的CSS类。 当表达式为false时,Angular删除选定的类。

===运算符测试给定的对象是否相同。 在模板语法指南中阅读有关[class]绑定的更多信息。

 <li>的最终版本如下所示:lib/app_component.html (ngFor with class.selected)

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<li *ngFor="let hero of heroes"
    [class.selected]="hero === selectedHero"
    (click)="onSelect(hero)">
  <span class="badge">{{hero.id}}</span> {{hero.name}}
</li>

点击“Magneta”后,列表应该如下所示:

回顾应用程序结构

您的项目应该有以下文件:

教程组件测试 本教程不包括测试,但是如果您查看示例代码,则会为本教程添加的每个新功能进行组件测试。 详细信息请参阅组件测试页面。

你走过的路

以下是您在此页面中所取得的成果:

英雄之旅(Tour of Heroes)应用程序显示可选英雄列表。 您将应用程序模板移到了自己的文件中。 您将Hero类移到lib / src下的自己的文件中。 你增加了选择英雄和显示英雄的细节的能力。 您了解了如何在组件模板中使用核心指令ngIf和ngFor。 您在CSS文件中定义了样式,并使用它们来设置应用程序的样式。 你的应用应该看起来像这个实例(查看源代码)。

前方的路

你已经扩大了英雄之旅的应用程序,但它还远远没有完成。 一个应用程序不应该是一个单一的组件。 在下一页中,您将将应用程序拆分为子组件,并使它们一起工作。

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2017/10/24 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
AngularDart4.0 英雄之旅-教程-08HTTP 顶
你离开的地方 在前一页中,您学会了在仪表板和固定英雄列表之间导航,沿途编辑选定的英雄。 这是这个页面的起点。
南郭先生
2018/08/14
11K0
AngularDart4.0 英雄之旅-教程-08HTTP
                                                    顶
AngularDart4.0 英雄之旅-教程-06服务 顶
不是一遍又一遍复制和粘贴相同的代码,而是创建一个可重用的数据服务,并将其注入到需要它的组件中。 使用单独的服务可使组件保持精简并专注于支持视图,并使用模拟服务对组件进行单元测试变得容易。
南郭先生
2018/08/14
3K0
AngularDart4.0 英雄之旅-教程-06服务
                                                    顶
AngularDart4.0 高级-组件样式 顶
Angular应用程序使用标准CSS进行样式化。 这意味着您可以将所有关于CSS样式表,选择器,规则和媒体查询的知识直接应用于Angular应用程序。
南郭先生
2018/08/14
2.3K0
AngularDart4.0 指南- 用户输入 顶
用户的操作,如点击链接,按下按钮,输入文字引发DOM事件。 本页说明如何使用Angular事件绑定语法将这些事件绑定到组件事件处理程序。
南郭先生
2018/08/14
3.5K0
AngularDart4.0 指南- 用户输入
                                                    顶
AngularDart4.0 英雄之旅-教程-07路由 顶
如果该应用程序尚未运行,请启动该应用程序。 在进行更改时,请通过重新加载浏览器窗口来保持运行。
南郭先生
2018/08/14
17.6K0
AngularDart4.0 英雄之旅-教程-07路由
                                                    顶
Angular 英雄编辑器
应用程序现在有了基本的标题。 接下来你要创建一个新的组件来显示英雄信息并且把这个组件放到应用程序的外壳里去。
HoneyMoose
2019/05/25
2.7K0
Angular 英雄编辑器
应用程序现在有了基本的标题。 接下来你要创建一个新的组件来显示英雄信息并且把这个组件放到应用程序的外壳里去。
HoneyMoose
2019/05/25
2.6K0
AngularDart4.0 指南- 模板语法一 顶
学习如何编写显示数据并在数据绑定的帮助下使用用户事件的模板。 Angular应用程序管理用户看到和可以做的事情,通过组件类实例(组件)和面向用户的模板的交互来实现这一点。 您可以熟悉模型 - 视图 - 控制器(MVC)或模型 - 视图 - 视图模型(MVVM)的组件/模板。 在Angular中,组件扮演控制器/视图模型的一部分,模板表示视图。
南郭先生
2018/08/14
5.2K0
AngularDart4.0 指南- 模板语法一
                                                    顶
AngularDart4.0 英雄之旅-教程-05多组件 顶
AppComponent正在做所有的事情。 一开始,它展示了一个英雄的细节。 然后,它成为一个英雄和英雄细节列表的主/细节形式。 很快就会有新的要求和能力。 您不能在一个组件之上填充所有功能; 这是不可维护的。
南郭先生
2018/08/14
1.8K0
AngularDart4.0 英雄之旅-教程-05多组件
                                                    顶
AngularDart4.0 指南- 显示数据 顶
您可以通过将HTML模板中的控件绑定到Angular组件的属性来显示数据。 在这个页面中,您将创建一个包含英雄列表的组件。 您将显示英雄名单的列表,并有条件地在列表下方显示一条消息。 最终的用户界面如下所示:
南郭先生
2018/08/14
5.3K0
AngularDart4.0 指南- 显示数据
                                                    顶
AngularDart4.0 英雄之旅-教程-03英雄编辑器
码云项目页:https://gitee.com/scooplolwiki/toh-1
南郭先生
2018/08/14
3.2K0
AngularDart4.0 英雄之旅-教程-03英雄编辑器
AngularDart4.0 指南-体系结构概述 顶
AngularDart(我们通常在这个文档中简单地称为Angular)是一个框架,用于在HTML和Dart中构建客户端应用程序。它是作为Angular包发布的,与 其他许多Dart包一样,可以通过Pub工具获得。
南郭先生
2018/08/14
8K0
AngularDart4.0 指南-体系结构概述 
                                                    顶
Angular 主从组件
把所有特性都放在同一个组件中,将会使应用“长大”后变得不可维护。 你要把大型组件拆分成小一点的子组件,每个子组件都要集中精力处理某个特定的任务或工作流。
HoneyMoose
2019/05/30
1.3K0
AngularDart4.0 指南- 依赖注入 顶
依赖注入是一个重要的应用程序设计模式。 它的用途非常广泛,几乎所有人都称之为DI。
南郭先生
2018/08/14
5.7K0
Angular快速学习笔记(2) -- 架构
0. angular 与angular js angular 1.0 google改名为Angular js 新版本的,2.0以上的,继续叫angular,但是除了名字还叫angular,已经是一个全新的开发框架了。 Angular 是一个用 HTML 和 TypeScript 构建客户端应用的平台与框架。 Angular 本身使用 TypeScript 写成的。它将核心功能和可选功能作为一组 TypeScript 库进行实现,你可以把它们导入你的应用中。 全新的Angular 是一个用 HTML 和 T
JadePeng
2018/05/28
5.3K0
AngularDart4.0 英雄之旅-教程-02启动应用
码云项目页:https://gitee.com/scooplolwiki/toh-0
南郭先生
2018/08/14
1.8K0
AngularDart4.0 英雄之旅-教程-02启动应用
AngularDart4.0 高级-属性(Attribute)指令 顶
结构指令改变了视图的结构。 两个例子是NgFor和NgIf。 在“结构指令”页面中了解它们。
南郭先生
2018/08/14
3.2K0
AngularDart4.0 高级-属性(Attribute)指令
                                                    顶
AngularDart 4.0 高级-HTTP 客户端 顶
大多数前端应用程序使用HTTP协议与后端服务进行通信。 Dart网络应用程序通常使用XMLHttpRequest(XHR)API执行此操作,使用dart:html库中的HttpRequest或更高级别的API(例如http包提供的内容)。
南郭先生
2018/08/14
9.7K0
AngularDart 4.0 高级-HTTP 客户端
                                                    顶
AngularDart4.0 高级-层级依赖注入器 顶
在Dependency Injection指南中你学会了基础的Angular依赖注入. Angular有一个层级依赖注入 系统. 实际上是一个与组件树相平行的注入器树. 你可以在组件树的任意层级重新配置注入器. 此指南探索此系统并使用它带来的好处. 尝试live example(view source).
南郭先生
2018/08/14
8730
AngularDart4.0 高级-层级依赖注入器
                                                    顶
AngularDart4.0 指南- 模板语法二 顶
Class绑定语法类似于属性(property)绑定。 以前缀类开始,可选地跟一个点(.)和一个CSS类的名字替代括号内的元素属性:[class.class-name]。
南郭先生
2018/08/14
30.1K0
AngularDart4.0 指南- 模板语法二
                                                    顶
相关推荐
AngularDart4.0 英雄之旅-教程-08HTTP 顶
更多 >
领券
社区富文本编辑器全新改版!诚邀体验~
全新交互,全新视觉,新增快捷键、悬浮工具栏、高亮块等功能并同时优化现有功能,全面提升创作效率和体验
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文