angular 基础与提高

英雄指南——英雄编辑器

2016-12-18  本文已影响23人  soojade

版本:v4.0.0+2

在教程的这一部分,你将修改启动程序来显示一个英雄的信息。然后你间添加编辑英雄数据的能力。完成后,应用看起来这样——在线示例 (查看源码)。

回顾上一章

在开始编写代码之前,让我们验证你是否有如下的文件结构。如果没有,回到前一章,查看详细介绍。

如果应用不运行了,启动应用。当你做出修改时,通过刷新浏览器保持继续运行。

显示英雄

AppComponent添加两个属性:一个表示应用名字的title属性,和一个表示名为 “Windstorm” 的英雄的hero 属性。

// lib/app_component.dart (AppComponent class)

class AppComponent {
  final title = 'Tour of Heroes';
  var hero = 'Windstorm';
}

现在,使用数据绑定到这些新属性,更新@Component注解中的模板。

// lib/app_component.dart (@Component)

template: '<h1>{{title}}</h1><h2>{{hero}} details!</h2>',

刷新浏览器,页面将显示标题和英雄名字。

双大括号是 Angular 的插值表达式语法。这些插值绑定组件的titlehero属性值,作为字符串,插入到 HTML 的标题标签中。

更多关于插值表达式的内容请看显示数据章节。

创建 Hero

英雄需要更多属性。把hero从一个字符串字面量转换成一个类。

创建一个具有 idname 属性的Hero 类。把这些属性添加到 app_component.dart文件的顶部附近,仅在 import 语句下面。

// lib/app_component.dart (Hero class)

class Hero {
  final int id;
  String name;

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

AppComponent类,重构组件的 hero 属性为 Hero 类型,然后以id1、以name为 “Windstorm”,初始化它。

// lib/app_component.dart (hero property)

Hero hero = new Hero(1, 'Windstorm');

因为我们把 hero 从一个字符串换成了对象,所以更新模板中的绑定,来引用 hero 的name属性。

template: '<h1>{{title}}</h1><h2>{{hero.name}} details!</h2>',

刷新浏览器,页面将继续显示英雄的名字。

添加多行 HTML 模板

为了显示英雄的所有属性,添加一个<div>来显示英雄的id属性,另一个<div>来显示英雄的name属性。为了使模板保持可读性,每个div独自占一行。

// lib/app_component.dart (multi-line strings)

template: '''
  <h1>{{title}}</h1>
  <h2>{{hero.name}} details!</h2>
  <div><label>id: </label>{{hero.id}}</div>
  <div><label>name: </label>{{hero.name}}</div>
''',

使应用名字可编辑

用户应该能够在一个<input>文本框中编辑英雄名字。文本框应该既能显示 应用的name属性,又能根据用户的输入更新 属性。

你需要在<input>表单元素和hero.name属性之间双向数据绑定。

使用双向绑定

重构模板中的英雄名字使其看起来如下:

<div>
  <label>name: </label>
  <input [(ngModel)]="hero.name" placeholder="name">
</div>

[(ngModel)]是 Angular 语法,绑定hero.name属性到文本框。数据在两个方向流动:从属性到文本框,从文本框又回到属性。

查看 ngModel 更多信息在表单模板语法

声明非核心指令

不幸的是,这样改变之后,程序立即崩溃了!

模板解析错误

如果你刷新浏览器,应用不会加载。要知道原因,查看pub serve输出。模板解析器不能识别ngModelAppComponent解析错误:

 Error running TemplateGenerator for forms|lib/src/hero_form_component.dart.
  Error: Template parse errors:
  Can't bind to 'ngModel' since it isn't a known native property or known directive. Please fix typo or add to directives list.
  [(ngModel)]="hero.name"
  ^^^^^^^^^^^^^^^^^^^^^^^

更新 pubspec

angular_forms库包含在它自己的包里。在 pubsepc dependencies中添加包:

// {toh-0 → toh-1}/pubspec.yaml

dependencies:
    angular: ^4.0.0
+  angular_forms: ^1.0.0

更新 @Component(directives:...)

尽管NgModelangular_forms库中是一个有效的 Angular 指令,但默认它不是可用的。

在模板中使用任意 Angular 指令之前,需要在组件的@Component注解的directives参数中列出它们。你可以单独的添加指令,或为了方便添加formDirectives列表(注意新的导入语句):

// lib/app_component.dart (directives)

import 'package:angular_forms/angular_forms.dart';

@Component(
  selector: 'my-app',
  // ···
  directives: const [formDirectives],
)

刷新浏览器,应用应该可用再次运行了。你可以编辑英雄名字并且在文本框上方的<h2>中立刻看到变化的反应。

你已走过的路

来盘点一下都构建了哪些内容。

你的应用看起来应该这样——在线示例 (查看源码)

完整的app_component.dart是这样的:

// lib/app_component.dart

import 'package:angular/angular.dart';
import 'package:angular_forms/angular_forms.dart';
@Component(
  selector: 'my-app',
  template: '''
    <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>
  ''',
  directives: const [formDirectives],
)
class AppComponent {
  final title = 'Tour of Heroes';
  Hero hero = new Hero(1, 'Windstorm');
}
class Hero {
  final int id;
  String name;
  Hero(this.id, this.name);
}

下一步

主从结构

上一篇 下一篇

猜你喜欢

热点阅读