Angular设计模式:MVC、MVVM还是MV*?

86

Angular 1.x(AngularJS)基于其双向数据绑定功能,更多或少遵循MV *设计原则。

Angular2采用了基于组件的UI,这个概念对React开发人员可能很熟悉。从某种意义上说,Angular 1.x控制器和指令混合为新的Angular 2组件。

这意味着在Angular 2中没有控制器和指令。相反,组件具有选择器,该选择器对应于组件表示的HTML标记以及@View,用于指定组件要填充的HTML模板。

Angular2仍然实现双向数据绑定,但不包括例如文章列表的显示组件和定义文章对象的类的模型:

class Article {
title: string;
link: string;
votes: number;

constructor(title: string, link: string, votes?: number){
    this.title = title;
    this.link = link;
    this.votes = votes || 0;
}

在MVC模式中,这被认为是模型。

考虑到这一点,Angular遵循最接近哪种设计模式?

6个回答

98

Angular 2并不是真正的MVC(但我认为你可以画出类比)。 它是基于组件的。 让我解释一下:

Angular 1是MVC和MVVM(MV *)。 Angular 1之所以具有开创性,原因之一是因为它使用了依赖注入。与Backbone和Knockout等其他JS框架相比,这是一个新概念。

然后React出现了,完全改变了前端架构。它让前端思考除了MVC和MVVM之外的其他选项。相反,它创建了基于组件的架构的想法。这可以被视为自HTML和JavaScript以来前端架构的最重要的转型之一。

Angular 2(和Angular 1.5.x)决定采取React的方法并使用基于组件的架构。但是,您可以在MVC,MVVM和Angular 2之间画出轻微的类比,这就是为什么我认为这可能有点令人困惑的原因。

话虽如此,在Angular 2中没有控制器或ViewModel(除非您手工制作它们)。相反,有组件,由模板(类似于视图),类和元数据(装饰器)组成。

例如,模型是保存数据的类(例如使用@angular / http返回数据的数据契约)。我们可以创建一个新类,添加方法和属性(逻辑),然后合并模型和类。这创建了类似于ViewModel的东西。然后我们可以在组件中使用这个ViewModel。

但是称组件的类或服务为ViewModel或Controller并不完全正确。组件包含模板和类。在我看来,这有点像Liskov的理论-鸭子不是鸭子-不要试图将MVC或MVVM模式强制到组件中,因为它们是不同的。将Angular 2视为组件。但是我可以理解人们为什么会画出类比以帮助他们的最初理解。

Angular还使用模块,这是JavaScript的即将推出的版本(ECMAScript 6)的一部分。这非常强大,因为JavaScript一直存在命名空间和代码组织问题。这就是组件导入和导出的功能所在。

有用的链接:

Angular 2与React:终极较量

Angular 2是MVC吗?


1
我不确定假设组件层次结构和单个组件结构是互斥的是否必要,因为在像Ext JS这样的框架中它们并不是。即使Angular不是MVVM,将视图绑定组件类属性视为视图模型对我来说也很有用,以便将实现视为随时间变化的状态而不是DOM的方法或过程性操作。与其他MVVM框架一样,这有助于减少混乱的代码和一般的复杂性。 - Trevor Karjanis

23

Angular 1 和 Angular 2 都遵循MVC(模型、视图、控制器)模式。

在 Angular 1 中,HTML 标记是视图,控制器是控制器,服务(用于检索数据)是模型。

在 Angular 2 中,模板是视图,类是控制器,服务(用于检索数据)是模型。

由于 Angular 是客户端框架,所以 Angular 遵循的 MVC 模式也可以称为 MVVC(模型、视图、视图控制器)。


能否再解释一下为什么要使用 MVVC?谢谢。 - Anatoly
20
服务不是模型,模型才是模型。通常在MVC相关的框架中,实际上有两种类型的模型:(1) 领域模型 (2) 将领域模型适配到视图的模型(有时称为ViewModel)。 - gusgorman
1
@gusgorman 在Angular 2+中,Service是模型,因为它检索数据,这是MVC架构中模型应该实现的功能。 - Don Dilanga
2
服务不是模型,服务只是可注入的逻辑,可能会或可能不会检索数据。 - Gerardo Buenrostro González
1
无效的答案 :( - afruzan
该服务可以用作一个模型,但最终它变成了全局状态,这在许多情况下都不是期望的。 - Clay Lenhart

13

我不太喜欢使用M**符号(有点滥用和模糊)。

无论如何,我的观点是,在Angular2中,最简单和最有效的方式是:

  • 类(在您的情况下可能是文章)代表模型。

  • 组件将视图(在模板中)和控制器(TypeScript逻辑)合并。

希望这有所帮助。


8

使用AngularJS的MVC和MVVM

MVC设计模式

首先,MVC设计模式不仅适用于AngularJS,您可能已经在许多其他编程语言中看到或实现了此模式。

MVC设计模式可以在AngularJS中看到,但在深入了解之前,让我们看看MVC设计模式包括哪些内容:

Model:模型就是数据。 View:视图表示这些数据。 Controller:控制器在两者之间进行协调。

在MVC中,如果我们更改视图中的任何内容,则不会在模型中更新。但在AngularJS中,我们听说有一种叫做双向绑定的东西,它启用了MVVM设计模式。

MVVM基本上包括三个部分:

模型 视图 视图模型 在MMVM设计模式中,控制器实际上被视图模型所取代。视图模型是一个JavaScript函数,类似于控制器,负责维护视图和模型之间的关系,但区别在于,如果我们在视图中更新任何内容,则会在模型中更新,如果更改模型中的任何内容,则会显示在视图中,这就是我们所说的双向绑定。

这就是为什么我们说AngularJS遵循MVVM设计模式。


2
“Model is nothing but data.”这种说法是错误的。实际上,模型不仅包括数据,还包括元数据、业务逻辑和数据库接口。同样,“Controller mediates between the two.”也是错误的。事实上,控制器并不起到调解作用。视图会对模型中发生的变化事件做出反应,而且并不需要控制器的提示。控制器的任务始于用户事件,但你甚至没有提到这点。 - IAM_AL_X
2
"View Model仅仅是一个JavaScript函数,类似于控制器"这种说法是错误的。 - afruzan
@GuidoMocha请编辑和更新答案,我想批准它。 - Ashish Kamble

5
在Angular(不包括版本2及以上)中,我们使用数据绑定功能。此数据绑定功能在ng应用程序中强制实施MVVM模式,因为在这种情况下控制器会导致V&M之间的绑定(视图的更改导致模型的更改,反之亦然)。因此,在MVC术语中,我们可以将“C”替换为“VM”,从而得到“MVVM”。

5

在我个人看来,如果你想使用一些约定,你可以使用MVVM在Angular 2中进行开发:

  1. 组件包含视图(模板)和视图模型(类)。
  2. 你只需要缺少模型,你可以创建一个正常的TypeScript类,并将其作为构造函数参数传递给视图模型。

这种技术与PRISM和WPF中可用的技术非常相似,在那里你可以使用MVVM(如果你想要的话)开发所有内容。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接