AngularJS客户端MVC模式?


72

到现在为止,我主要是利用Struts 2SpringJQuery用于构建Web应用程序技术堆栈。关键是,提到的堆栈使用服务器端MVC模式。Web浏览器的主要作用仅限于请求/响应周期(+客户端验证)。数据检索,业务逻辑,接线和验证是服务器端的主要职责。

我对AngularJS框架的疑问很少,这些疑问是由我读过的下列引言所启发的:


AngularJS教程中

对于Angular应用,我们鼓励使用模型-视图-控制器(MVC)设计模式来分离代码并分离关注点。

Wikipedia模型-视图-控制器

模型-视图-控制器(MVC)是一种体系结构,用于将信息的表示形式与用户与之的交互分开。该模型由应用程序数据和业务规则组成,控制器控制输入,将其转换为模型或视图的命令


AngularJS使用客户端MVC模式。因此,我想除了以某种方式在客户端也包括验证逻辑之外,没有别的选择了吗?

编写健壮的AngularJS应用程序的最佳方法是什么?客户端上的MVC和服务器端上的某种MC(模型,控制器)?

这是否意味着,MODEL和CONTROLLER以一种方式重复(客户端/服务器)?

我知道我的问题有些奇怪,但是我认为原因是我某种程度上习惯于传统的服务器端MVC模式。我确定有人已经完成了相同的过渡。

Answers:


117

根本不是一个奇怪的问题-我一直试图将Angular卖给许多Java开发人员,他们问这个问题。我在学习的时候问过自己(我还在学习,顺便说一句)

如果您按照描述使用了“常规” java webapp并对其进行了角度化,则必须首先使用服务器并将其设为RESTful API。删除JSP等。这实际上是IMO编写Angular应用程序的难点-正确设置REST API。对于我来说,决定进入服务器所需的逻辑的关键是将其视为纯API,并暂时忘记它将具有前端

这个问题确实对我有帮助-如果有人尝试保存给定的资源并且该资源没有有效数据,则没有前端可以告诉他们-他们直接攻击了API,因此API需要拒绝它。因此,后端负责深度验证。这也适用于您的业务逻辑。假设有人使用刚刚的API,它会变得清晰你的服务器需要做。

服务器还需要以(可能)json格式出售数据(我使用Spring MVC + Jackson),因此服务器负责将模型暴露给Angular,并与数据库进行通信。

那么,Angular端的MVC是什么?

  • 模型:来自REST API的数据。如果API正在出售JSON,则这些对象将已经是1st类javascript对象。
  • 视图:HTML和需要操作DOM时的指令
  • 控制器:(以及从控制器中提取的自定义服务。)
    • 查询REST API并将所需的View放在$ scope上
    • 提供指令的回调,以响应可能随后需要回调服务器的事件。
    • 验证:通常通过对指令的回调。 可能会有些重叠,你已经把服务器验证的,但你不希望你的用户等待服务器来验证一切-客户应该知道的东西有关验证给用户的即时反馈。
    • 业务逻辑:与验证几乎相同。

但是,为什么在客户端和服务器中重复逻辑?通常是因为您没有编写一个应用程序,而是在编写两个独立的东西:

  1. REST API,需要没有前端的强大功能和可用性
  2. 需要立即向用户反馈,而不必等待服务器的GUI。

因此,简短的答案-通过忘记会有UI来正确使用REST API,Angular中的内容将更加清晰。


1
仅供参考,自编写本文以来,我决定不使用REST,而是使用与Amazon EC2 api尽可能相似的HTTP api。REST不会削减它。抱歉,餐厅员工!
Roy Truelove

2
下一代框架解决了客户端和服务器中逻辑的重复问题,请参阅meteor.com
stefcud 2013年

1
流星不一定能解决重复问题,但也会带来限制。拥有RESTful API和WebUI非常有用(使用相同的REST API编写本机应用程序)。IMO流星是一个很好的概念,但是它与服务器端紧密结合在一起,无法在任何情况下都有用。当然,使用流星可以轻松解决很多问题;)
Kr0e

这确实是一个很好的答案,但是根据我的经验,在尝试ExpressJS之后,Java需要在静态API应用方面进行一些改进,而我放弃了Spring MVC。
Thiago C. S Ventura 2014年

1
@RoyTruelove哇!大!+1 btw。嗯,IMO,最令人困惑的部分是:But why the duplication of logic in the client and in the server? Mostly because you're not writing one app, you're writing two independent things: 1) a REST API that needs to be robust and usable without a front end 2) a GUI that needs to give immediate feedback to a user and not necessarily wait for a server. So, short answer - get the REST API right by forgetting that there will be a UI, and what goes into Angular will be much clearer. 谢谢!
php-dev

13

我认为“业务逻辑”一词在这里有点用词不当。客户端应用程序的“业务”是处理用户界面的业务。它不会像安全规则和专有逻辑或其他敏感的知识产权。

所以在Angular中,除法是(通常):

  • 控制器(controller):用于操纵UI背后的数据(作用域)。
  • 指令:用于设置DOM以通过范围与控制器进行通信,以及用于操作DOM。
  • 模板(视图):为DOM元素分配指令。
  • 范围(模型或视图模型):用于在系统的所有部分之间传送数据。
  • 服务:可注入,可重用的代码位。通常用于处理Ajax,cookie或其他I / O之类的依赖项。

实际上几乎是MVVM,而不是MVC。

至于您的“业务”逻辑或规则...任何需要安全性的东西都必须始终在服务器级别得到保护。


几年来,AngularJS更接近于MVC(或其客户端变体之一),但是随着时间的流逝,由于许多重构和api的改进,现在它更接近MVVM – $ scope对象可以被认为是ViewModel由我们称为控制器的函数修饰。
imanis_tn 2014年

5
以上评论摘自AngularJS团队的帖子:plus.google.com/app/basic/stream/…–
永远学习

8

重要的是要了解,在某些版本的MVC模式中,数据以及操纵数据的逻辑都位于“模型”层(“控制器”层除了绑定外什么也不做)。但是,在AngularJS中,数据($ scope)仅驻留在“模型”层中,而操纵数据($ scope)的逻辑位于“控制器”层中。

AngularJS“ MVC”


3

我喜欢@Roy TrueLove所说的话。但是,我要说的是,这是使用angularjs的最终方法。当然,如果您想获得angular的最大好处,就必须学习以这种方式进行应用。我祈祷有一天能在那里。

同时,在学习过程中以及过渡到完全将angularjs用作客户端的主要工作方式的过程中,您可以开始将其用于这里和那里的一些小任务,并逐渐习惯于它及其实现方式思维。

我鼓励逐渐拥抱它,然后慢慢地慢慢走,但是可以肯定的是,我保证。

Angularjs旨在支持这种方法,因为它可以完成最小的任务,也可以完成最大的任务。例如,这是我第一次使用angular只是为了在用户键入id时显示名称。


1
绝对真实。我鼓励办公室中的其他开发团队使用Angular,即使他们的应用程序中包含的JavaScript很小。
罗伊·特鲁伊洛夫

3

我同意这里的答案。一些更多的评论。在编写应用程序时,您首先需要专注于问题域。并创建一些实际业务的软件模型。例如,如果您的问题域是购物,那么您需要建模的一些需求可能包括:

  • 信用卡应该是有效的。
  • 如果您使用品牌X的信用卡付款,您将获得10%的折扣。
  • 购物车应至少包含一项以执行结帐
  • 这些商品必须有库存,然后用户才能将其添加到购物车中

这些要求的实施将为您的问题领域建模,这就是您的业务逻辑。

Angular是一个前端框架和工具包。这是一个Web前端。如果在Web前端中实现此功能,您将失去从其他前端或界面(例如移动或桌面应用程序)重用模型的机会。因此,理想情况下,您的业务逻辑实现需要与任何用户界面框架分离,也应与任何持久性框架分离。然后,您将拥有将处理用户界面问题并与业务逻辑对象进行通讯的界面对象。这可以是Spring MVC控制器和/或Angular控制器或服务。

您可以查看一个示例应用程序,该应用程序遵循此处提到的原理。


3

我似乎也有这个问题,因为有些组织只是热衷于寻求新技术-“我想要云...等待,我想要轻量级”,很难证明它是否值得转向更轻巧的框架。

我一直使用Spring / JBoss seam / JSF和MVC框架开发Web应用程序。大多数时候,Java脚本将驻留在表示层验证中,而主要操作类/实体和业务逻辑将驻留在Java代码中。在Angular上进行了一些基本的动手操作之后,我开始了解它们对MVC的含义,因为他们在表示层上抽象了另一层,在前端我们可以拥有自己的视图和控制器。要回答您的问题,就像每个人的评论一样,最好的方法是将其放置在表示层上。

至于安全性的观点,我认为繁重或敏感的业务规则应该驻留在服务器端,因为我们不想将其公开。如果业务逻辑开发不完善,则可以轻松地发现我们代码的弱点并加以利用。

我的想法是,像Angular这样的框架就像是一家小商店/ SOHO的处理客户,他们有几个人并且真正高效快捷,它们很好地迎合了面对业务和交付/接收商品(REST,JSON)的客户。他们确实具有指定的角色和任务,但是某些工作人员执行的任务不仅仅是任务。该商店还容易受到小偷或强盗的攻击,因为他们通常不强调严格的安全性。

至于像Spring / Struts 2这样的服务器端框架,可以想象一下一家现代公司(CMM级别5),它具有不同的管理级别,并且能够处理更大的业务(批处理作业,Web服务,企业总线)。他们确实会与客户打交道,但不能直接与客户打交道,通常会通过经纪人甚至是零售店。在安全方面,公司会更强大,并且经常在前门提供证券,或者将重要信息保护在保险箱中(加密/登录)。


2

我的方法始终是自下而上的方法。从数据库设计开始,使用适当构造的/相关的表,并在需要时使用存储过程,然后将实体框架添加到解决方案中;如果没有EF选项,则使用ADO.Net。然后开发业务逻辑和模型,以使数据进出数据库。

建立模型后,我们现在可以走两条路线:开发MVC控制器和/或开发WebAPI控制器。两个控制器都可以访问模型,这仅是实例化类并调用方法的问题。

现在,您可以选择设置由MVC控制器控制的MVC视图,或者设置完全独立的HTML页面或SPA(NodeJS上托管的单页应用程序)集。

使用完全独立的HTML页面集,您将需要使用带有Get,Post,Put和Delete方法的WebAPI控制器,并确保前后包含令牌以标识您的客户端,并启用CORS(用于跨源请求) )

使用MVC视图,您可以使用控制器属性和/或会话来标识客户端,而无需担心CORS,甚至可以根据需要将视图设置为强类型。不幸的是,如果您有一组UI开发人员,他们将必须使用相同的MVC解决方案。

在这两种情况下,您都可以使用AngularJS在/控制器之间来回传输数据。

恕我直言,AngularJS控制器的概念与C#MVC或C#WebAPI控制器不同。AngularJS控制器包含所有JavaScript逻辑以及通过“ ApiFactory”对端点的调用,而C#控制器不过是服务器端接受并响应UI请求的端点。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.