Angular2组件开发—为模板应用样式(二)

ShadowDom - 封装私有样式

Angular2采用ShadowDom作为组件的渲染基础,这意味着组件被渲染到独立的Shadow Tree上,这很好,可以实现DOM对象和样式的良好封装:

但问题是,除了Chrome之外的大多数的浏览器目前还不支持ShadowDom,因此,Angular2 提供了三种将模板渲染到DOM的策略。

以下面的模板为例,我们看三种策略下的渲染结果差异:

1 @View{
2     template:"<h1>hello</h1>",
3     styles:["h1{color:red}"]
4 }

全局仿真策略/EmulatedUnscopedShadowDomStrategy

采用这个策略时,Angular2将模板直接插入DOM树,并将模板的样式原封不动地插入head头部。这意味着 不同组件之间的样式可能冲突 : 在右边的示例代码中,你可以清楚的看到,EzApp组件的h1样式污染了其他的 h1元素,所有的h1都变成红色了。

示例代码渲染后的DOM如下:

这个策略不需要浏览器原生支持ShadowDom,是当前版本(alpha.28)的默认策略。

作用域仿真策略/EmulatedScopedShadowDomStrategy

采用这个策略时,Angular2将模板直接插入DOM树,对模板的样式重新定义CSS选择符后 插入head头部。由于样式进行了重命名,所以不同组件之间的样式不会冲突

示例代码在这个策略下的渲染结果是:

这个策略也不需要浏览器原生支持ShadowDom。

原生策略/NativeShadowDomStrategy

采用这个策略时,Angular2将在组件的宿主DOM对象上建立一个ShadowDom树,这颗树与主DOM树是隔离的,所以,这是实现Web组件的理想方案:

如果浏览器原生支持ShadowDom,那么应当使用这个策略。

例如:

 1 <!doctype html>
 2 <html>
 3 <head>
 4     <meta charset="utf-8">
 5     <title>template - shadowdom strategy</title>
 6     <script type="text/javascript" src="lib/[email protected]"></script>
 7     <script type="text/javascript" src="lib/angular2.dev.js"></script>
 8     <script type="text/javascript" src="lib/system.config.js"></script>
 9 </head>
10 <body>
11     <h1>我是H1,我在组件外</h1>
12     <ez-app></ez-app>
13
14     <script type="module">
15         import {bind,Component,View,bootstrap} from "angular2/angular2";
16
17         @Component({selector:"ez-app"})
18         @View({
19             template:"<h2>我是H2,我在组件内</h2>",
20             styles:["h2{color:red}"]
21         })
22         class EzApp{}
23
24         bootstrap(EzApp);
25
26     </script>
27 </body>
28 </html>

结果如下:

时间: 2024-11-01 08:44:49

Angular2组件开发—为模板应用样式(二)的相关文章

Angular2组件开发—为模板应用样式

styles - 设置模板样式 组件既然处于UI层,就应当好看些,好看是构造良好用户体验的一部分.Angular2的 组件模板基于HTML,那么显然,我们需要通过样式表/CSS来调整组件的外观. 和模板类似,我们有两种方法为组件设置CSS样式: 1. 内联样式 可以使用组件View注解的styles属性来设置内联样式: 1 @View({ 2 styles:[` 3 h1{background:#4dba6c;color:#fff} 4 `] 5 }) 2. 外部样式 也可以把样式定义在单独的文

Angular2组件开发—模板的逻辑控制(二)

使用分支逻辑 如果组件的模板需要根据某个表达式的不同取值展示不同的片段,可以使用NgSwitch系列指令来动态切分模板.比如右边示例中的广告组件EzPromotion,需要根据来访者性别的不同推送不同的广告: NgSwitch包含一组指令,用来构造包含多分支的模板: NgSwitch NgSwitch指令可以应用在任何HTML元素上,它评估元素的ngSwitch属性值,并根据这个值 决定应用哪些template的内容(可以同时显示多个分支): 1 <any [ng-switch]="exp

Angular2组件开发—模板语法(二)

directives - 使用组件 在Angular2中,一个组件的模板内除了可以使用标准的HTML元素,也可以使用自定义的组件! 这是相当重要的特性,意味着Angular2将无偏差地对待标准的HTML元素和你自己定义的组件.这样, 你可以建立自己的领域建模语言了,这使得渲染模板和视图模型的对齐更加容易,也使得模板的语义性 更强: 声明要在模板中使用的组件 不过,在使用自定义组件之前,必需在组件的ViewAnnotation中通过directives属性声明这个组件: 1 @View({ 2 d

Angular2组件开发—模板的逻辑控制(三)

NgFor- 循环逻辑 如果希望利用一组可遍历的数据动态构造模板,那么应当使用NgFor指令. 例如示例中的EzStar组件,用来展示演员的作品列表: 迭代 NgFor指令应用在template元素上,对ngForOf属性指定的数据集中的每一项 实例化一个template的内容: 1 <template ng-for="" [ng-for-of]="items"> 2 <li>----------</li> 3 </temp

Angular2组件开发—模板语法(六)

#var - 局部变量 有时模板中的不同元素间可能需要互相调用,Angular2提供一种简单的语法将元素 映射为局部变量:添加一个以#或var-开始的属性,后续的部分表示变量名, 这个变量对应元素的实例. 在下面的代码示例中,我们为元素h1定义了一个局部变量v_h1,这个变量指向 该元素对应的DOM对象,你可以在模板中的其他地方调用其方法和属性: 1 @View({ 2 template : ` 3 <h1 #v_h1>hello</h1> 4 <button (click)

Angular2组件开发—调用服务(二)

注入 - Injector 在前一节的示例代码中,组件EzAlgo直接在构造函数中实例化了一个EzAlog对象,这造成了EzApp和EzAlgo的强耦合,我们可以使用Angular2的注入器/Injector进行解耦: 注入器就像婚姻介绍所,男方在婚介所登记心仪的女性特点,约好见面地点,然后, 坐等发货即可.比如上图: EzApp组件(男方)使用Component注解的Injector属性向Angular2框架(婚介所)声明其依赖于EzAlgo(登记心仪的女性特点),并在其构造函数的参数表中使用

Angular2组件开发—模板语法(五)

(event) - 监听事件 在模板中为元素添加事件监听很简单,使用一对小括号包裹事件名称,并绑定 到表达式即可: 上面的代码实例为DOM对象h1的click事件添加监听函数onClick(). 另一种等效的书写方法是在事件名称前加on-前缀: 1 @View({template : `<h1 on-click="onClick()">HELLO</h1>`}) 例如: 1 <!doctype html> 2 <html> 3 <h

Angular2组件开发—属性与事件(一)

属性声明 - 暴露成员变量 属性是组件暴露给外部世界的调用接口,调用者通过设置不同的属性值来定制 组件的行为与外观: 在Angular2中为组件增加属性接口非常简单,只需要在Component注解的properties属性中声明组件的成员变量就可以了: 1 //EzCard 2 @Component({ 3 properties:["name","country"] 4 }) 上面的代码将组件的成员变量name和country暴露为同名属性,这意味着在EzApp的模

Angular2组件开发—调用服务(三)

注入一个复杂的服务 EzAlgo相当简单,使用new或者使用Injector来获得一个实例看起来差别不大.那如果我们的EzApp组件要使用Http服务呢? 第一眼看上去,Http服务显然是一个真正有用的服务 - 因为看起来相当的复杂 - Http依赖于XHRBackend和BaseRequestOptions,而XHRBackend又依赖于BrowserXHR. 我们可以有两种方法获得一个Http的实例,以便通过它获得网络访问的功能: 1. 使用new进行实例化 如果我们使用传统的new方式创建