Angular 2、使用 body 作为根选择器,而不是 my-app

Angular 2, using body as root selector, instead of my-app

对于根组件使用 <body> 标签而不是某些 <my-app> 标签有什么缺点吗?

import 'package:angular2/angular2.dart';
@Component(
    selector: 'body',
    template: '''
      <h1>My First Angular 2 App</h1>

      <div>{{greet}}</div>
    ''',
    styles: const ['''
      :host {
        height: 100vh;
      }
      h1 {
        color: red;
      }
    '''])
class AppComponent {
  String greet = 'Hello world';
}

(这里的代码是Dart,但我希望它足够接近ES6,其他人可以理解的打字稿。)

我不常看到这种情况,所以我想这是有充分理由的,但这对我来说似乎不错,否则你基本上有两个根组件,body 和 my-app。

老实说,这个框架还很新,我们还没有真正的答案。话虽这么说,从技术上讲,如果您使用 <body> 作为根元素,我认为不会有任何问题,但从概念上讲,我认为它会让您陷入困境,最终您将回到使用自定义根元素稍后添加元素。

例如,页面上可能有一些您想要的静态样式或项目 angular 无法控制,但不属于 <body> 例如,如果使用 CSS 框架,如 bootstrap,您可能希望将您的站点包装在 class="container" 中,或者可能有一个静态页眉或页脚,仅包含链接。这些当然也可以在组件中轻松处理。

另一个要考虑的项目是浏览器支持,这在某些浏览器中可能工作得很好,但在其他浏览器中就不行,还不确定。

所以我猜答案是 "We don't know yet",因为在以前的版本中这是 ng-app 的一种非常普遍的做法,它可能是被考虑过的东西,尽管大多数例子来自团队展示了使用自定义根元素作为推荐方式,可能有一个我们还不知道的原因。

进一步思考:使用 <html> 作为根元素怎么样...?谁知道呢

你可以并且不会发生任何不好的事情(除非你有两个 body 标签)。不过,不要这样做,因为:

缺点

选择器应该反映出您应用的独特之处。

如果您希望 Angular 控制整个页面,只需使用 body 作为选择器。 另见 How do I change the body class via a typescript class (angular2)

如果您使用 'body' 作为您应用的选择器,它会起作用,但存在一些问题:

  • Web Component 规范说要使用 custom elementscustom attributes 并且它不使用官方 html 元素。

  • 官方style guide建议对你的组件使用'custom prefix',比如'myComponent'。另外,如果你想在 'component-selector-prefix' 配置中使用一些像 tslint 这样的 linter 来检查它,它会抛出一个使用 'body' 选择器而不带前缀的警告。

  • 如果选择器(body)里面有一些元素,它们会被隐藏 angular,也许你会想把一些 'scripts' 放在 body 里面或另一个组件,例如 'webpack' 将脚本放在正文的底部,也许它会工作但不如预期的那样...

最佳。

以上所有朋友对缺点的看法都是正确的。但是 <body foo-root> 呢?

import 'package:angular2/angular2.dart';
@Component(
    selector: 'body[foo-root]',
    template: '''
      <h1>My First Angular 2 App</h1>

      <div>{{greet}}</div>
    ''',
    styles: const ['''
      :host {
        height: 100vh;
      }
      h1 {
        color: red;
      }
    '''])
class AppComponent {
  String greet = 'Hello world';
}