创建并理解Angular2的TODO列表

首先

通过确认由Angular2 Dart版本创建的简单Todo List应用的运行,通过解释该代码来了解Angular2的基础。

这篇文章是在Angular2发布beta版之后,我在年末年始开始学习Angular2,在此基础上参考了这篇文章,特意将代码改写为Dart版本,并增加了一些内容。如果发现任何错误,请在评论栏中通知我。

如果您想阅读TypeScript版的解释,或者想要读简明的说明,请阅读原文。

Angular2 Dart
Angular2 Dart 中

Angular2的Dart版基本上是将使用TypeScript开发的Angular转译成Dart的版本(通过ts2dart),因此API几乎相同。(但根据开发进展的不同,Dart版的部分API可能会有所延迟,或者某些功能可能只在Dart版中以试验性支持的方式提供。)因此,如果学会了TypeScript版,也可以毫无问题地进行Dart版的开发,反之亦然。

此外,由于Dart的语义简单且学习成本较低,所以在熟悉TypeScript或Java等语言的情况下学习Dart相对容易。此外,Dart的SDK非常完善且稳定,特别是对于流、异步/等待等异步API和区域的引入,它是一个强力支持异步编程的语言。

如果要升级现有项目到Angular2,目前采用ES6、ES5或TypeScript是合适的选择,但对于新项目,考虑采用Dart也是一种不错的选择。

另外,用Dart编写的示例代码已经在Github上放置。
https://github.com/ntaoo/angular2_dart_todo/releases/tag/20160104-qiita

我需要确认Todo List的操作是否正常。

Dart SDK的安装

如果尚未安装Dart SDK,请按照以下步骤进行安装:https://www.dartlang.org/downloads/
如果您使用的是Mac系统,则可以通过Homebrew进行安装。

brew tap dart-lang/dart
brew install dart --with-content-shell --with-dartium

确认行动

我要克隆 angular2_dart_todo。

git clone https://github.com/ntaoo/angular2_dart_todo.git

进行公共获取

请运行 pub get。pub get 类似于 npm install。

pub get

开发服务器

请接下来执行pub serve命令。这将启动Dart项目的开发服务器(默认为http://localhost:8080)。

pub serve

Dartium-达特琳

在Dart项目中,我们使用Dartium作为开发用浏览器。对于Mac用户,请使用以下命令以checked mode启动Dartium。

DART_FLAGS='--checked' open /usr/local/opt/dart/Chromium.app

在实际的开发中,最好使用WebStorm等IDE启动Dartium。

当您访问 http://localhost:8080 时,应该会显示以下界面。

Screen Shot 2016-01-02 at 12.15.20 AM.png

顺便提一下,如果在Chrome或其他现代浏览器中打开URL,开发服务器会自动根据需要将JS代码进行编译。因此,显示需要花费一些时间(大约几十秒)。

Screen Shot 2016-01-01 at 11.22.52 PM.png

使用搭载DartVM的Dartium可以直接运行Dart代码,无需将其编译为JS,因此构建过程会瞬间完成。不需要考虑编译时间。只需重新加载Dartium选项卡,即可实现快速地进行代码更改和构建的循环。由于可以使用调试器,因此在开发过程中应使用Dartium。

既然如此,我就试着构建一下。

在部署时,需要将Dart编译为JavaScript等进行构建。因此,我们需要确认一下。使用pub build命令可以完成包括从Dart到JavaScript的编译在内的构建过程。

pub build

我将尽快启动本地服务器并进行确认。

cd build/web
python -m SimpleHTTPServer

它应该能在现代浏览器上正常运行。

在 build/web/main.dart.js 文件中,应用程序的整个 JavaScript 代码被编译并合并为一个文件。这个 main.dart.js 文件大小为 460KB,压缩后为 127KB。可以说,相对于像 Dart 和 Angular2 这样丰富的框架来说,这个大小相当合理。

Angular 团队一直致力于减小 Dart 版本编译后的 JS 代码的大小,并且在准备进入 Production Ready 阶段时,预计会比现在更小。


提示:创建Dart项目需要从零开始。

在开始一个新的Dart项目时,使用Stagehand会非常方便。它类似于Yeoman的项目生成器。

此外,从零开始手动创建也并不困难。例如,执行mkdir angular2_todo && cd angular2_todo命令,创建pubspec.yaml文件并编写以下内容。

name: todo_app
version: 0.1.0
dependencies:
  angular2: 2.0.0-beta.0
  browser: ^0.10.0
  dart_to_js_script_rewriter: ^0.1.0
transformers:
- angular2:
    entry_points: web/main.dart
- dart_to_js_script_rewriter

然后执行pub get。这个命令将设置可使用项目中声明的依赖包,通过pubspec.yaml文件。
然后,在项目目录的根目录下创建web和lib目录,这样就完成了最基本的Dart应用程序项目的结构。此外,准备web/index.html文件,并执行pub serve命令,dev server将启动。非常简单。


引导(从这里开始)

现在进入正题。让我们来看一下代码。

请注意

由于 Angular2 在 2016 年 1 月时处于 Beta 版阶段,因此其 API 可能会出现破坏性更改的可能性。


lib/todo_list.dart是本次应用程序的根组件。

library todo_app.todo_list;

import "package:angular2/angular2.dart";

@Component(
    selector: 'todo-list',
    templateUrl: './todo_list.html',
    styleUrls: const ['./todo_list.css']
    
class TodoList {
}

“package:angular2/angular2.dart”被导入,这样所有Angular2的功能都被导入了。
在TodoListclass上添加@ComponentAnnotation。Annotation是Dart的功能,在Angular2中使用它来声明TodoListclass是Angular的Component,并附加元数据。

在TypeScript版中,使用了装饰器。至少在Angular2中,尽管{}和const声明的有无存在差异,但语法大体上是相同的。

在这里,selector:中使用了CSS选择器的语法,用来声明Component对应的Element是。同样地,templateUrl:和styleUrls:被用来声明template和style的URL。

可以使用SASS或LESS等代替CSS,但需要编辑构建过程。可能需要添加转换器选项等技巧来实现。另外,采用类似Polymer的CSS变量也是一个不错的选择。

我们来看看`web/index.html`和`web/main.dart`中编写的哪些样板代码来加载这个包含整个应用程序的“组件。

<head>
  ......
  <script defer src="main.dart" type="application/dart"></script>
  <script defer src="packages/browser/dart.js"></script>
</head>
<body>
  <todo-list>Loading...</todo-list>
</body>

(packages/browser/dart.js)是一个小脚本,用于在开发时使用Dartium以外的浏览器进行验证时,动态地将Dart文件的路径替换为编译后的JS文件的路径。在开发过程中,您无需担心此事。

library todo_app.web;

import 'package:angular2/bootstrap.dart';
import "package:todo_app/todo_list.dart";

main() => bootstrap(TodoList);

引用angular2/bootstrap.dart和todo_list.dart,并将TodoList组件作为此Angular2应用程序的根组件进行指定和启动,这只是一个简单的示例(在后续的说明中,我会添加依赖注入)。

顺便提一下,由于’package:angular2/bootstrap.dart’已被标记为@deprecated,所以很可能会很快发生API变化。

查看package:angular2/platform/browser.dart的注释或angular.io的文档等可以了解到这个API的详细信息。它还解释了与Angular1的区别,Angular2应用程序的设计思想以及多个Angular2应用程序的混合使用。

此外,与TypeScript版不同,Dart不需要像SystemJS这样的解决方案,只需使用Dart的包管理系统即可。

网络组件

好的,那么Angular2的组件可能是Web组件吗?我将打开Dartium或Chrome的检查器进行确认。

Screen Shot 2016-01-02 at 6.57.51 AM.png

我无法找到ShadowDOM。相反,元素被赋予了一个奇怪的属性-ghost-yfy-1,而其子元素被赋予了_ngcontent-yfy-1的属性。

Screen Shot 2016-01-02 at 7.26.22 AM.png

三种模式

我们已经发现Angular2在实现Web组件的优点方面有一些伪装。那么,我们是否可以将Angular2组件转换为真正的Web组件呢?让我们稍微探究一下Angular2 Dart的实现。

/**
 * Defines template and style encapsulation options available for Component's [View].
 *
 * See [ViewMetadata#encapsulation].
 */
enum ViewEncapsulation {
  /**
   * Emulate `Native` scoping of styles by adding an attribute containing surrogate id to the Host
   * Element and pre-processing the style rules provided via
   * [ViewMetadata#styles] or [ViewMetadata#stylesUrls], and adding the new Host Element
   * attribute to all selectors.
   *
   * This is the default option.
   */
  Emulated,
  /**
   * Use the native encapsulation mechanism of the renderer.
   *
   * For the DOM this means using [Shadow DOM](https://w3c.github.io/webcomponents/spec/shadow/) and
   * creating a ShadowRoot for Component's Host Element.
   */
  Native,
  /**
   * Don't provide any template or style encapsulation.
   */
  None
}

Angular2是使用TypeScript开发的,然后通过转译为Dart,以pub package的形式提供。转译后的代码保持了源代码的可读性,并且注释也得到了适当的维护。


在Angular2组件的封装中,使用enum定义了3种模式。

    • Emulated: 上記説明の通り、擬似的なカプセル化を行う。

 

    • Native: レンダラーの提供するカプセル化を利用する。(DOMの場合はShadow DOM)

 

    None: templateとstyleのカプセル化を行わない。

默认是模拟模式。因此,在之前的例子中,没有指定任何内容,所以应用了模拟模式。

让我们尝试一下封装:指定ViewEncapsulation.Native。

@Component(
    selector: 'todo-list',
    templateUrl: './todo_list.html',
    styleUrls: const ['./todo_list.css'],
    encapsulation: ViewEncapsulation.Native,

在Chrome中打开,那个奇怪的属性消失了,取而代之的是ShadowRoot。非常漂亮和好看!

Screen Shot 2016-01-02 at 6.37.50 AM.png

然而,如果一个浏览器不支持Web组件技术,也就是没有实现Shadow DOM,会发生什么呢?

当我尝试用Firefox打开时,果然出现了异常错误:NullError:receiver.webkitCreateShadowRoot未定义,导致应用无法正常启动。这很正常,因为我们并没有实施相关操作。同时也可以确认,在Angular2内部并没有使用Web Components的Polyfill。

应该选择哪种模式?

从2015年春天到秋天,Web Components的进展大致上可以说在各个浏览器供应商之间的一致在很大程度上推进,尤其是Safari正在积极推进ShadowDOM的实现,这是一则令人振奋的消息,让人对整体发展抱有很大希望。然而,截至2016年1月,在Chrome系列以外的浏览器仍然没有得到支持。

因此,除非有特殊原因,只支持Chrome系列浏览器或View不是基于DOM(虽然还没有仔细调查,但是可能是考虑了NativeScript),否则在目前阶段不应指定ViewEncapsulation.Native。也不应使用ShadowDOM Polyfill。

所有现代浏览器都已经完全实现了Custom Elements和ShadowDOM,并且已经修复了浏览器实现的错误,情况已经稳定下来。因此,在这个情况下,仍然采用默认的ViewEncapsulation.Emulated是合理的。

而且,我自己没有确认过这个操作,但是选择ViewEncapsulation.None可能适用于在遵守CSS的BEM命名约定的前提下降低Angular2引入成本的目的,这取决于组织和项目的情况。

简单的数据绑定

在Angular2中,数据绑定变得更简单了,理解其工作原理也更加容易了。

属性绑定 (Shǔ Xì

首先,只需在Dart的类中添加属性。这是Dart属性的语法本身。与Angular 1不同,它没有范围的概念。取而代之的是,组件将成为对应视图的上下文。

class TodoList {
  String newItem = 'test';

通过将该property绑定到DOM元素的property上,可以使用[value]=”newItem”将其设定为以下内容。

<input class="new-todo" [value]="newItem">

实际的代码使用[(ngModel)]=”newItem”实现双向绑定,但为了说明,我这里提供了临时的代码。

只需这样,就可以将输入元素的value属性进行数据绑定了。

Screen Shot 2016-01-02 at 12.15.20 AM.png

在属性绑定中,数据始终以一种单向流动的方式从组件传递到相应的视图。

事件绑定

事件绑定也是简单的。我们会使用Dart的常规语法来编写TodoList类的方法(addItem())。

class TodoList {
  String newItem = 'test';

  addItem() {
    this.store.addItem(this.newItem);
    this.newItem = '';
  }

只要写成以下的样子 (click)=”addItem()”,就可以将addItem()绑定到click事件上。

<button class="add" (click)="addItem()">Add</button>

在事件绑定中,数据始终以单向流动的方式从视图传递到对应的组件。

双向绑定

属性绑定通过[]语法始终从组件流向视图,事件绑定通过()语法始终从视图流向组件。

要实现将用户的输入更新反映到newItem属性上,最好的方法是使用(input)=”newItemChanged($event)”进行事件绑定。($event是DOM事件。事件绑定的表达式可以接受$event作为参数。)

<input class="new-todo"
      [value]="newItem" (input)="newItemChanged($event)">
newItemChanged(KeyboardEvent event) {
  InputElement target = event.target;
  this.newItem = target.value;
}

通过这种方式,我们成功实现了双向绑定。

本地模板变量

在先前的例子中,我解释了expression可以接受DOM的Event作为参数的能力。

<input class="new-todo"
      [value]="newItem" (input)="newItemChanged($event)">

由于Event是DOM API,因此它具有通用性,但处理和类型检查稍微麻烦也是事实。有没有更简单的方法呢?使用本地模板变量可以简化操作。

<input class="new-todo"
      #todoInput [value]="newItem" (input)="newItemChanged(todoInput.value)">

通过使用#todoInput,可以声明一个名为todoInput的变量。在这里,可以通过todoInput.value来引用Input的value属性。

以下是TodoList类的方法,它与Expression相对应。

newItemChanged(String value) {
  this.newItem = value;
}

通过去除处理键盘事件并提取事件目标值的代码,使代码变得简洁而清晰。

NgModel (双向绑定模块)

此外,您可以通过[(ngModel)]来简化这个过程。

<input class="new-todo" [(ngModel)]="newItem">

只需要以下这个:
这样就可以了。Dart的方法也不再需要了。[(ngModel)]是属性绑定和事件绑定的组合语法糖,在处理输入时特别方便。如果想要了解[(ngModel)]的内部结构,请阅读ANGULAR 2 TEMPLATE SYNTAX或查看源代码等。

虚拟事件

作为添加待办事项的操作,除了点击“Add”按钮外,应该也支持按下“Enter”键。在Dart代码中,通过过滤keyup事件的按键代码来写就非常简单,多亏了Dart的Event Stream。然而,Angular2还为我们提供了更为方便的方法。

<input class="new-todo" [(ngModel)]="newItem" (keyup.enter)="addItem()">
<button class="add" (click)="addItem()">Add</button>

在这里,只需键入 (keyup.enter),它就会过滤掉键码。非常方便。

为什么将Data Binding的语法从Angular1进行了改变?

请观看ng-conf 2015的主题演讲,因为决策背后的背景非常有趣。(这是近一年前的信息,我很后悔最近才意识到这一点。)

要提取的要点之一是

    • Html AttributeはDOM Propertyの値がserializeされたもので、その後にPropertyの値が更新されてもAttributeの値は更新されないケースもある。

 

    • Attributeと異なりPropertyはserializeしなくても良い。よってmodelの値を型を保持したまま子componentに渡すことができる。{{}}expressionのserializeが不要になる。

 

    ng-*の多数のdirectiveが必要なくなり、DOM propertyにbindするだけで良くなる。
Screen Shot 2016-01-02 at 9.16.49 AM.png

这是个旁白,但由于设计思想的差异,简单地比较并没有太多意义。然而,相比Polymer1,我觉得Angular2的组件更易于编写。

添加商店

我们将从这里开始添加Model层。在这里,我们将借用Flux模式的概念,添加一个Store。Store负责处理业务逻辑并存储数据。(为了尊重原始文章的思想和代码,我们选择称之为Store。)

class TodoItem {
  String text;
  TodoItem(this.text);
}

class TodoStore {
  List<TodoItem> items;

  TodoStore() : this.items = [];
}

首先,我们先直接在TodoList组件中实例化它。之后再改进为依赖注入的方法。

import './todo_store.dart' as model;

final store = new model.TodoStore();

@Component({ ... })
class TodoList {
  String newItem = 'test';
  model.TodoStore store;
  // 略
}

此外,在这个简单的应用程序中,定义一个动作并添加一个调度程序,并通过它来驱动存储器的方式过于夸张,并不适合作为示例。因此,在这里我们做了简化,只是将存储器的实现限制在直接从TodoList组件接收消息上。

这个 TodoStore 保持了一个 TodoItem 的 List,用 ngFor 渲染它。

<section class="main">
  <ul class="todo-list">
    <li *ngFor="#item of items">
      <div class="view">
        <label></label>
      </div>
    </li>
  </ul>
</section>

希望Dart版本能够编写成#item in items,而不是使用of。

依赖注入 (DI)

在Angular2中,我们仍然需要使用依赖注入(DI)来实现TodoStore的单例模式,就像在Angular1中创建Service并注入到Controller中一样。

在TodoList类中,我们添加了model.TodoStore类的store属性,并在构造函数中进行了相应的指定。

import './todo_store.dart' as model;
@Component(
  // 略
)
class TodoList {
  String newItem = 'test';
  model.TodoStore store;

  TodoList(this.store);
  // 略
}   

另外,TodoList(this.store)将:

TodoList(model.TodoStore store) {
  this.store = store;
}

可以用中文进行转述。

只需将TodoStore添加到bootstrap()函数中即可完成。

library todo_app.web;

import 'package:angular2/bootstrap.dart';
import "package:todo_app/todo_list.dart";
import 'package:todo_app/todo_store.dart';

main() => bootstrap(TodoList, [TodoStore]);

请查看有关依赖注入的详细信息。

添加TodoItem的功能

由于添加了 Store,我们将添加 Todo 项的功能。

@Component(
  // 略
)
class TodoList {
  String newItem = 'test';
  model.TodoStore store;

  TodoList(this.store);

  addItem() {
    this.store.addItem(this.newItem);
    this.newItem = '';
  }
  // 略
}
class TodoStore {
  // 略
  addItem(String newItem) {
    this.items.add(new TodoItem(newItem));
  }
 // 略
} 

只需这样,通过对Store添加项目以更新store属性,并更新newItem属性,这将反映在视图中。

Screen Shot 2016-01-03 at 9.40.28 AM.png

Angular2是如何在何时以及如何将数据更新反映到视图中的?

Angular 2是如何在何时将数据更新反映到视图中的?

在Angular1中,我们使用Scope和Digest Cycle的概念来管理数据更新。这对于简单的应用程序非常方便,但是当应用程序变得复杂且需要管理的数据增加时,会导致不必要的更新检查增加,性能下降,以及复杂的Digest Cycle控制背景下开发人员可能需要根据启发式准则编写代码来调用Digest Cycle。尤其是在性能较低的移动设备上,这可能成为一个问题。

Angular2引入了一种名为Change Detection的机制来解决这个问题。通过这个机制,实现了类似于“Digest Cycle”的隐藏和显著的性能提升。

这个Change Detection是使用”Zone”(JS, Dart)来对浏览器的异步API进行补丁,实现自动在各个事件周围(如DOM事件和Http请求)进行适当执行的设计。与Angular1不同的是,它经常从根组件开始,通过深度优先搜索来遍历组件树,并检查与属性绑定的值,然后更新视图。(注意: 需要进一步确认细节)。

此外,还有一个名为开发者模式的功能。当程序员编写会破坏变更检测更新管理的代码时,它会在运行时抛出错误并提示程序员进行修正。需要确保这方面的功能正常运行。

请参阅Angular2的Change Detection以及CHANGE DETECTION IN ANGULAR 2以获取更多关于Change Detection的解释。

添加子组件

实际的Angular2应用程序应该由许多组件构成一棵树结构。 在这个TodoList示例中,为了说明子组件的例子,我们将尝试改变当前只有一个根组件TodoList的结构。

请将todo_list.html的其中一部分进行重新叙述。

<div class="view">
  <label></label>
</div>

将其视为View模板,并创建TodoItem组件。

import "package:angular2/angular2.dart";
import "./todo_store.dart" as model show TodoItem;

@Component(
    selector: 'todo-item',
    templateUrl: './todo_item.html',
    styleUrls: const ['./todo_item.css']
)    
class TodoItem {
  @Input()
  model.TodoItem item;
}

请注意@Input()注解。添加了这个注解的property将成为该组件的公共API,使其可以进行绑定。以下是将其替换为的实际例子。

<li *ngFor="#item of store.items">
  <todo-item [item]="item"></todo-item>
</li>

在”item”中,由于@Input()注解声明了TodoItem组件的公共属性,该属性与Store的TodoItem实例绑定在一起。

添加删除按钮

我已经确认了绑定到子组件属性的例子。下面我们通过添加删除按钮,并将组件视为DOM元素,来看一个组件触发事件的例子。

<div class="view">
  <label>{{item.text}}</label>
  <button (click)="doneClicked()" class="destroy"></button>
</div>

在TodoItem组件的模板中添加一个删除按钮。

library todo_app.todo_item;

import "package:angular2/angular2.dart";
import "./todo_store.dart" as model show TodoItem;

@Component(
    selector: 'todo-item',
    templateUrl: './todo_item.html',
    styleUrls: const ['./todo_item.css']
)    
class TodoItem {
  @Input()
  model.TodoItem item;

  @Output()
  EventEmitter<model.TodoItem> done = new EventEmitter();

  doneClicked() {
    this.done.add(this.item);
  }
}

为了触发来自的事件,我在这里添加了一个带有@Output()注释的EventEmitter。并且通过点击Delete按钮来将该EventEmitter绑定到触发事件的方法中。

现在,我们已经设置好了,在TodoItem组件中触发done事件,接下来让我们在父组件的TodoList组件中来绑定这个done事件吧。

<todo-item [item]="item" (done)="removeItem($event)"></todo-item>
removeItem(model.TodoItem item) {
  this.store.removeItem(item);
}

在这里,我要求删除TodoStore中的model.TodoItem。

這樣一來,刪除按鈕的實現就完成了。

进一步提高变化检测的效率

让我们实际检查一下,Change Detection是在何时执行,并通过属性绑定从Store的模型对象TodoItem中访问数据。

<div class="view">
  <label>{{item.text}}</label>
  <button (click)="doneClicked()" class="destroy"></button>
</div>

在这里,我们将使用Dart的Setter和Getter功能,在每次访问text时将日志输出到控制台。

class TodoItem {
  String _text;

  get text {
    print('getting value for text ${this._text}');
    return this._text;
  }

  set text(String value) {
    this._text = value;
  }

  TodoItem(this._text);
}

请注意以下代码中的文本值 ${this._text}。

我会在浏览器上进行操作确认。

Screen Shot 2016-01-04 at 10.21.37 AM.png

每次在输入框中输入键时,都会输出大量日志。换句话说,在此处更改检测会检查每个TodoInput的文本值是否有变化,并确认没有变化。从实际的Todo List应用程序操作来看,这显然是不必要的检查,并且似乎是低效的。

Angular2在浏览器事件发生时,会每次执行改变检测,并以深度优先搜索的方式默认遍历所有组件。尽管这显得效率低下,但实际上它的性能非常高,因此在大多数情况下并不成问题。不过,我们是否能够明显地省略掉不必要的检查呢?

不可变性

Angular2的组件可以分别指定ChangeDetectionStrategy。通过这个指定可以实现更加高效的检查。

在本次的Todo List应用程序规范中,考虑到TodoItem组件的数据不会在组件生成后进行更新,因此可以视其为实际上的不可变对象。因此,在组件生成后,可以跳过Change Detection的检查而不会有问题。通过将ChangeDetectionStrategy修改为OnPush,可以指示该行为。

@Component(
    selector: 'todo-item',
    // 略
    changeDetection: ChangeDetectionStrategy.OnPush)
class TodoItem {
  // 略
}
Screen Shot 2016-01-04 at 11.13.19 AM.png

现在,每次键入Key时不再浪费检查每个TodoItem组件,而是仅在生成时进行一次检查。

进一步的学习可以参考以下资料:
关于Angular2的变更检测(重复)
在Angular 2中的变更检测(重复)
Angular,不可变性和封装性

也许尝试探索Change Detection的实现会很有趣。

总结

自從推出測試版以來,我個人的感覺是,Angular2是一個易於理解語法和操作,同時也非常高效的網絡框架。此外,這只是我的個人印象,Angular2解決了我在Angular1時代感受到的沮喪,讓它在我的心智模型中自然適應,讓我在編寫代碼時感到舒適愉快。

随着Angular2的使用和与Immutable库和Flux模式的结合等等,将会出现许多新的实践方法。我也希望自己在追随Angular2的过程中能够与大家分享。

此外,Dart是一种非常高效和出色的语言,但是当使用Reflection(Mirror)API时,如果没有仔细设置,可能导致在编译成JS时Tree Shaking失败,从而导致代码大小增加的问题。我认为这可能是导致可靠的Web框架难以建立的重要原因。Reflection问题有望通过Reflectable得到解决,但是Angular2在内部引入了类似于Reflectable的机制,以确保在编译成JS后代码的大小保持较小,这对于Dart来说,Angular2可以成为一个杀手级的框架可以期待的。

希望2016年成为Angular 2和Dart激发WebApp反应式开发热潮的一年。

个人的待办事项

    • Client side routing (For SPA)

 

    • Dart版ののhttp moduleについて。Dart SDKのものをそのまま使うのか各自工夫するのか、それともAPIをTypeScript版に合わせた薄いwrapperが提供されるのか。

 

    • Angular Material for Angular2の進捗(pub packageとしてすでにbeta versionが提供されているが、まだ初期段階に見える)

 

    • Angular2は必要に応じてPolymer Element等のWeb ComponentをProperty BindingやEvent Bindingで取り扱うことができるが、例えばPolymerDartとの組み合わせは実際に実用的なのかどうか。

 

    • Angular2独自のreflectableの仕組み

 

    Angular2のtransformerの仕組み
bannerAds