1- 尽可能保持平面化的目录结构
2- 当有 7个或更多文件时才新建目录;
3- 为每个组件新建一个目录,保存它的 .ts,.html,.css,.spec 等文件;
4- 在单个特性范围内,把所有共享的文件放到 shared 目录,在一个特性范围内,分离出组件共享的文件;
5- 把目录的名字命名为它包含的特性名字;
6- 布局组件
7- 把定义总体布局的组件放到 shared 目录;
8- 把共享的布局组件放到 shared 目录下它自己的独立目录里;
9- 创建和导入封装桶
1+ # Angular Dev Guaid
2+ ## 目录
3+ 把所有应用程序的源代码都放到名叫 app 的目录里。所有内容都遵循每个文件单个特性的原则。每个组件、服务和管道都在自己的文件里。所有第三方程序包都被保存到其它目录里而不在 app 目录里,我们不会修改它们,所以不希望它们弄乱我们的应用程序。使用本指南介绍的文件命名约定。
4+ ### 尽可能保持平面化的目录结构
5+
6+ - 当有 7个或更多文件时才新建目录
7+ - 为每个组件新建一个目录,保存它的 .ts,.html,.css,.spec 等文件;
8+ - 在单个特性范围内,把所有共享的文件放到 shared 目录,在一个特性范围内,分离出组件共享的文件;
9+ - 把目录的名字命名为它包含的特性名字;
10+ ### 布局组件
11+ - 把定义总体布局的组件放到 shared 目录;
12+ - 把共享的布局组件放到 shared 目录下它自己的独立目录里;
13+ ### 创建和导入封装桶
1014新建一个文件,用来导入、归集和重新导出项目。该技巧被称作 封装桶 。把该封装桶文件命名为 index.ts ;
1115为惰性加载目录名字加前缀 +,使用组件路由器来惰性加载可以路由的特性。
1216命名文件到这个程度:可以从名字立刻知道它包含了什么,代表了什么;
1317文件名要具有说明性,并保证文件中只包含一个组件;
1418避免 创建包含很多组件、服务或者混合体的文件;
15- 把模板和样式提取到它们自己的文件
19+ ### 把模板和样式提取到它们自己的文件
1620当超过三行的时候,把模板和样式提取到一个单独的文件
1721当组件名字为 [ component-name] 的时候,命名它的模板为 [ component-name] .component.html
1822文件结构如下图所示:
19- 文件
23+ ## 文件
2024每个文件只定义一样东西 (比如服务或者组件 ),把文件大小限制在 400行代码以内;
2125定义小函数,限制在 75 行之内;
2226遵循同一个模式来描述符号的特性和类型。推荐的模式为 feature.type.ts,使用惯用的后缀来描述类型,比如 * .service 、 * .component 、 * .pipe、* .model;
2327在描述性名字里面,使用横杠来分隔单词;
24- 启动
28+ ### 启动
2529把应用的引导程序和平台相关的逻辑放到名为 main.ts 的文件里;
2630避免 把应用逻辑放到 main.ts 里。考虑把它放到组件或服务里面;
2731
28- 组件与指令命名
32+ ### 组件与指令命名
2933以它们所代表的东西命名;
3034使用大写驼峰命名法来命名所有符号 ( 类 ) 。保持符号的名字与它所在的文件名字相同;
3135把符号的类型 ( 比如组件、服务、指令等 ) 附加到符号名的后面;
3236如下所示:
33- 符号名 文件名
34- export class HeroesComponent heroes.component.ts
35- export class HeroListComponent hero-list.component.ts
36- export class ValidationDirective validation.directive.ts
37- 服务
37+ 符号名 | 文件名
38+ --|--
39+ export class HeroesComponent | heroes.component.ts
40+ export class HeroListComponent | hero-list.component.ts
41+ export class ValidationDirective | validation.directive.ts
42+
43+ ### 服务
3844使用大写驼峰命名法来命名服务;
3945当不能从它们的名字里清楚的看出它们是什么的时候 ( 比如它们的名字是名词时 ) ,添加 Service 后缀;
4046如下所示:
41- 符号名 文件名
42- export class HeroDataService {} hero-data.service.ts
43- export class CreditService {} credit .service.ts
44-
45- 指令的选择器
47+ 符号名| 文件名
48+ --|--
49+ export class HeroDataService {} | hero-data .service.ts
50+ export class CreditService {} | credit.service.ts
51+ ### 指令的选择器
4652使用小驼峰命名法来命名指令的选择器,Angular 2 HTML 解析器是大小写敏感的,它识别小写驼峰写法;
4753保持指令里定义的属性名字与它们绑定的视图 HTML 属性名字一致;
4854为组件的选择器使用自定义前缀。比如,前缀 tod 是从 Tour of Heros 来的,前缀 admin 代表了 admin 的特性区域;
4955使用前缀来识别特性区域或者应用程序本身;
5056如下所示
57+ ``` ts
5158@Component ({
5259 selector: ' admin-users'
5360})
@@ -56,28 +63,35 @@ export class UsersComponent {}
5663 selector: ' [tohValidate]'
5764})
5865export class ValidateDirective {}
59- 管道名
66+ ```
67+ ### 管道名
6068为所有管道使用前后一致的命名约定,用它们的特性来命名;
6169如下:
70+ ``` ts
6271@Pipe ({ name: ' ellipsis' })
6372export class EllipsisPipe implementsPipeTransform { }
64-
65- 编程约定
66- 类
67- 使用大写驼峰命名法来命名类;
73+ ```
74+ ## 编程约定
75+ ### 类
76+ 使用大写驼峰命名法来命名类
77+ ``` ts
6878export class ExceptionService {
6979 constructor () { }
7080}
71- 常量
81+ ```
82+ ### 常量
7283用 const 声明变量,除非它们的值在应用的生命周期内会发生变化;
73- 把常量名拼写为小驼峰格式;
84+ 把常量名拼写为小驼峰格式
85+ ``` ts
7486export const mockHeroes = [' Sam' , ' Jill' ];
75- 接口
87+ ```
88+ ### 接口
7689使用大写驼峰命名法来命名接口;
7790不要在接口名字前面加 I 前缀;
78- 属性和方法
91+ ### 属性和方法
7992使用小写驼峰命名法来命名属性和方法;
8093避免使用下划线为前缀来命名私有属性和方法;
94+ ``` ts
8195import { Injectable } from ' @angular/core' ;
8296@Injectable ()
8397export class ToastService {
@@ -95,12 +109,14 @@ export class ToastService {
95109 console .log (this .message );
96110 }
97111}
98- 内联 Input 和 Output 属性装饰器
99- 使用 @Input 和 @Output , 而非 @Directive 和 @Component 装饰器里面的 inputs 和 outputs 属性;
100- 把 @Input () 或者 @Output () 放到它们装饰的属性的同一行;
101- 成员顺序
112+ ```
113+ ### 内联 Input 和 Output 属性装饰器
114+ 使用 ` @Input ` 和 ` @Output ` , 而非 ` @Directive ` 和 ` @Component ` 装饰器里面的 ` inputs ` 和 ` outputs ` 属性;
115+ 把 ` @Input() ` 或者 ` @Output() ` 放到它们装饰的属性的同一行;
116+ ### 成员顺序
102117把属性成员放到顶部,方法成员紧随其后;
103118先放公共成员,再放私有成员,并按照字母顺序排列;
119+ ``` ts
104120export class ToastComponent implementsOnInit {
105121 // public properties
106122 message: string ;
@@ -132,10 +148,12 @@ export class ToastComponent implementsOnInit {
132148 window .setTimeout (() => this .hide (), 2500 );
133149 }
134150}
135- 把逻辑放到服务里
151+ ```
152+ ### 把逻辑放到服务里
136153把组件类中的逻辑限制到只有视图需要的逻辑。所有其它逻辑都应该被放到服务;
137154把可以重复使用的逻辑放到服务里,保持组件简单并聚焦于它们预期目的;
138155错误的方式
156+ ``` ts
139157/* avoid */
140158import { OnInit } from ' @angular/core' ;
141159import { Http , Response } from ' @angular/http' ;
@@ -164,7 +182,9 @@ export class HeroListComponent implementsOnInit {
164182 // hide the spinner
165183 }
166184}
185+ ```
167186正确的方式
187+ ``` ts
168188import { Component , OnInit } from ' @angular/core' ;
169189import { Hero , HeroService } from ' ../shared' ;
170190@Component ({
@@ -183,14 +203,18 @@ export class HeroListComponent implementsOnInit {
183203 this .getHeroes ();
184204 }
185205}
186- 不要给输出属性加前缀
187- 命名事件时,不要带前缀 on;
188- 命名事件处理方法时,带前缀 on ,紧跟事件名字;
206+ ```
207+ ### 不要给输出属性加前缀
208+ 命名事件时,不要带前缀 ` on ` ;
209+ 命名事件处理方法时,带前缀 ` on ` ,紧跟事件名字
210+ ``` ts
189211export class HeroComponent {
190212 @Output () savedTheDay = new EventEmitter <boolean >();
191213}
192- 使用指令来加强已有元素
214+ ```
215+ ###使用指令来加强已有元素
193216当你需要有无模板的展示逻辑时,使用属性型指令。
217+ ``` ts
194218@Directive ({
195219 selector: ' [tohHighlight]'
196220})
@@ -199,10 +223,13 @@ export class HighlightDirective {
199223 // do highlight work
200224 }
201225}
202-
203- <divtohHighlight >Bombasta</div >
204- 使用 HostListener 和 HostBinding 类装饰器
205- 使用 @HostListener 和 @HostBinding ,而非 @Directive 和 @Component 装饰器的宿主属性。与属性或方法名字相关联的@HostBinding 或者 @HostListener 应该只在一个地方被修改:在指令的类里。反过来,如果我们使用宿主属性,我们需要在控制器内修改属性声明,然后在指令相关的元数据里修改
226+ ```
227+ ``` html
228+ <div tohHighlight >Bombasta</div >
229+ ```
230+ ### 使用 HostListener 和 HostBinding 类装饰器
231+ 使用` @HostListener ` 和 ` @HostBinding ` ,而非 ` @Directive ` 和 ` @Component ` 装饰器的宿主属性。与属性或方法名字相关联的` @HostBinding ` 或者 ` @HostListener ` 应该只在一个地方被修改:在指令的类里。反过来,如果我们使用宿主属性,我们需要在控制器内修改属性声明,然后在指令相关的元数据里修改
232+ ``` ts
206233@Directive ({
207234 selector: ' [tohValidator]'
208235})
@@ -212,35 +239,39 @@ export class ValidatorDirective {
212239 // do work
213240 }
214241}
215- 服务
216- 在同一个注入器内,服务是单例
242+ ```
243+ ### 服务
244+ #### 在同一个注入器内,服务是单例
217245在同一个注入器内,把服务当做单例使用。使用它们来共享数据和功能。
246+ ``` ts
218247export class HeroService {
219248 constructor (private http : Http ) { }
220249 getHeroes() {
221250 return this .http .get (' api/heroes' )
222251 .map ((response : Response ) => <Hero []>response .json ().data );
223252 }
224253}
225- 单一职责
254+ ```
255+ #### 单一职责
226256新建单一职责的服务,把它封装在自己的环境内;
227257当服务成长到超出单一用途时,新建一个服务;
228- 提供一个服务
258+ #### 提供一个服务
229259在被共享范围内的顶级组件里,将服务提供到 Angular 2 的注入器里;
230260Angular 2 注入器是层次性的。在顶层组件提供服务时,该服务实例在所有该顶级组件的子级组件中可见并共享。
231261
232262当不同的两个组件需要一个服务的不同的实例时,上面的方法这就不理想了。在这种情况下,我们最好在需要崭新和单独服务实例的组件里提供服务
233263
234- 使用 @Injectable () 类装饰器
264+ #### 使用 ` @Injectable() ` 类装饰器
235265当使用类型作为令牌来注入服务的依赖时,使用 @Injectable 类装饰器,而非 @Inject 参数装饰器。
236266Angular 的依赖注入机制,是根据在服务的构造函数里面的类型的声明,来解析所有服务的依赖的。
237- 数据服务
238- 分离数据调用
267+
268+ #### 数据服务: 分离数据调用
239269把数据操作和数据互动重构到服务里;
240270让数据服务来负责 XHR 调用、本地储存、内存储存或者其他数据操作;
241271生命周期钩子
242272实现生命周期钩子接口
243273实现生命周期钩子接口,避免在方法名字拼写错误时,造成无意间没有调用钩子的可能。
274+ ``` ts
244275@Component ({
245276 selector: ' toh-hero-button' ,
246277 template: ` <button>OK</button> `
@@ -250,23 +281,29 @@ export class HeroButtonComponent implementsOnInit {
250281 console .log (' The component is initialized' );
251282 }
252283}
284+ ```
285+
286+ ## 编码风格:
287+ - 使用空格代替tab,建议是使用4个空格
288+ - 杜绝var声明变量,使用` const ` 或` let ` 来声明所有局部变量。如果变量不需要被重新赋值,默认应该使用` const ` 。应该拒绝使用关键字` var `
289+ - 优先使用箭头函数
290+ - 优先使用` for..of `
291+ - 每次只声明一个变量
292+ - 不能省略分号,每个语句都要以分号结尾。不要依赖于JS自动添加分号的功能
293+ - 常量命名规范,常量命名应该使用全大写格式,并用下划线分割
294+ - 使用模板字符串取代连接字符串,在处理多行字符串时,模板字符串比复杂的拼接字符串要表现的更出色
295+ - 尽量使用单引号包裹普通字符串,不使用双引号。如果字符串中包含单引号字符,应该使用模板字符串
296+
297+ ## 编程常用技巧
298+
299+
300+
253301
254302
255303
256- 编码风格:
257- 1. 使用空格代替tab,建议是使用4个空格, 与Java风格一致(google 建议使用2个空格)
258- 2. 不能省略分号,每个语句必须以分号结尾。不允许依赖于JS自动添加分号的功能。
259- 3. 不推荐代码水平对齐,会添加若干多余的空格
260- 4. 杜绝var声明变量,使用const或let来声明所有局部变量。如果变量不需要被重新赋值,默认应该使用const。应该拒绝使用关键字var。
261- 5. 优先使用箭头函数
262- 6. 使用模板字符串取代连接字符串,在处理多行字符串时,模板字符串比复杂的拼接字符串要表现的更出色。
263- 7. 不要使用连续行风格长字符串,在JS中,\也代表着续行符。
264- 8. 优先使用for..of
265- 9. 常量命名规范,常量命名应该使用全大写格式,并用下划线分割
266- 10. 每次只声明一个变量
267- 11. 使用单引号,只允许使用单引号包裹普通字符串,禁止使用双引号。如果字符串中包含单引号字符,应该使用模板字符串。
268- https://google.github.io/styleguide/jsguide.html
304+ ## 参考资料
305+ [ https://google.github.io/styleguide/jsguide.html ] ( https://google.github.io/styleguide/jsguide.html )
269306
270- https://segmentfault.com/a/1190000013972464
307+ [ https://segmentfault.com/a/1190000013972464 ] ( https://segmentfault.com/a/1190000013972464 )
271308
272- https://www.cnblogs.com/huangenai/p/7246651.html
309+ [ https://www.cnblogs.com/huangenai/p/7246651.html ] ( https://www.cnblogs.com/huangenai/p/7246651.html )
0 commit comments