AngularJS框架中的领域模型

背景

由于最近工作的需要,后端同学需要开发后台系统的web界面,所以调研了一些主流的组件化前端框架,比如reactjs,vuejs,angularjs等。其中angularjs属于具有完整体系的一个web框架,也就是说不需要额外的前端库支持,就可以完成一个前端应用。对于不是很了解前端技术栈的后端同学来说比较适合,同时与AngularJS整合的Typescript,它的语法也和Java比较接近,而且是强类型的语言。

Angular框架核心模型

当然这篇文章并不是用来谈论前端框架的技术选型的,而是想从Angular框架的角度来讲讲前端开发领域的模型是什么?


AngularJS总体架构图

从这个架构图上我们可以看到里面有很多概念:

  • 模块(Module)
  • 组件(Components)
  • 模版(Templates)
  • 元数据(Metadata)
  • 数据绑定(Data binding)
  • 指令(Directives)
  • 服务(Services)
  • 依赖注入(Dependency injection)

这里很多概念可能后端开发同学反而更加熟悉,比如服务和依赖注入。当然我们今天主要是关注核心模型,所以我用模型图把概念里面的模型单拎出来:


AngularJS领域模型

这里我们忽略了元数据和依赖注入这两个概念,这两个我们可以理解成双向绑定的声明方式(元数据),服务的调用方式(依赖注入)所以不放入核心模型中探讨。

模块(Modules)

所谓模块其实是语言级的概念,因为javascript并没有语言级的模块支持,然而几乎所有的js框架中都有这个概念,甚至有很多专门用于实现js模块化的框架。
所以一个模块不光可以包含组件(Components)(实现层面就是一个用@NgModule声明的class),服务(Services)(实现层面是一个普通的class),还可以包含值变量、函数、类等等。
当然Angular的模块是要依赖语言的包机制实现的,一个典型的Angular模块:

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';

@NgModule({
  imports:      [ BrowserModule ], // 依赖的外部类
  providers:    [ Logger ], // 提供出去的服务
  declarations: [ AppComponent ], // 属于这个模块的视图类,比如components、directives、pipes
  exports:      [ AppComponent ], // 提供外部访问的类
  bootstrap:    [ AppComponent ] // 声明模块的根组件
})
export class AppModule { }

AngularJS里面没有applicaiton的概念,所以就用一个根模块来表达,如下:

import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app.module';

platformBrowserDynamic().bootstrapModule(AppModule);

AngularJS里面也没有显示libraries的概念,所以也是用模块来表达的。


Angular libraries

组件(Components)

一个组件主要是控制着屏幕上的一部分视图,比如整个应用的导航链接。

export class HeroListComponent implements OnInit {
  heroes: Hero[];
  selectedHero: Hero;

  constructor(private service: HeroService) { }

  ngOnInit() {
    this.heroes = this.service.getHeroes();
  }

  selectHero(hero: Hero) { this.selectedHero = hero; }
}

在编写组件的时候我们需要关注组件生命周期的扩展钩子:

生命周期的扩展钩子

模版(Templates)

一个组件的视图就是一个模版,它包含一个html的框架用来告诉Angular如何渲染组件。

<h2>Hero List</h2>
<p><i>Pick a hero from the list</i></p>
<ul>
  <li *ngFor="let hero of heroes" (click)="selectHero(hero)">
    {{hero.name}}
  </li>
</ul>
<hero-detail *ngIf="selectedHero" [hero]="selectedHero"></hero-detail>

模版可以包含指令,还可以引用子组件:

组件树

指令(Directives)

指令是用来告诉Angular框架如何渲染(转化成DOM结构)。一个指令就是带有@Directive声明的一个类。一个组件本质上也就是一个关联模版的指令。
除了组件型的指令以外,还有结构型的指令,比如下面的模版就包含两个框架自带的结构型的指令:

<li *ngFor="let hero of heroes"></li>
<hero-detail *ngIf="selectedHero"></hero-detail>

其次还有一种属性型的指令,用于扩展html标签的属性功能,比如提供值绑定能力。

<input [(ngModel)]="hero.name">

当然可能还有其他类型的指令,比如处理布局等等,当然你也可以自定义新的指令。

服务(Services)

服务很大程度上就是一个普通的类,但是我们一般会给它分配一个明确的职责,让它提供某一种特定的能力。比如:

  • 日志服务
  • 数据服务
  • 消息总线
  • 税务计算器
  • 应用程序配置

日志服务样例:

export class Logger {
  log(msg: any)   { console.log(msg); }
  error(msg: any) { console.error(msg); }
  warn(msg: any)  { console.warn(msg); }
}

Angular没有明确服务的约束,但是提供了对服务的依赖注入功能:

constructor(private service: HeroService) { }
@Component({
  moduleId: module.id,
  selector:    'hero-list',
  templateUrl: './hero-list.component.html',
  providers:  [ HeroService ]
})

框架就会做自动匹配,效果如下图:


依赖注入

总结

我们今天主要从领域模型的角度去了解AngularJS的总体架构,核心模型主要有模块、组件、模版、指令、服务,从中我们可以感觉到从核心模型的角度去理解一个复杂系统的设计是很有帮助的,往往能很快的抓到系统设计的重心。

参考资料

Angular架构概述

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 218,607评论 6 507
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,239评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,960评论 0 355
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,750评论 1 294
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,764评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,604评论 1 305
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,347评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,253评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,702评论 1 315
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,893评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,015评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,734评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,352评论 3 330
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,934评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,052评论 1 270
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,216评论 3 371
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,969评论 2 355

推荐阅读更多精彩内容