原文出处: http://www.cnblogs.com/whitewolf/p/4581254.html ( 转载后格式较乱,建议读原文

2015-06-16 16:47 by 破狼,9381阅读,1评论,收藏,编辑

在开始介绍angular原理之前,我们有必要先了解下mvvm模式在angular中运用。虽然在angular社区一直将angular统称为前端MVC框架,同时angular团队也称它为MVW(Whatever)框架,但angular框架整体上更接近MVVM模式。下面是Igor Minar发布在Google+https://plus.google.com/+IgorMinar/posts/DRUAkZmXjNV的文章内容:

MVC vs MVVM vs MVP. What a controversial topic that many developers can spend hours and hours debating and arguing about.

For several years +AngularJS was closer to MVC (or rather one of its client-side variants),but over time and thanks to many refactorings and api improvements,it’s Now closer to MVVM – the $scope object Could be considered the viewmodel that is being decorated by a function that we call a Controller.

Being able to categorize a framework and put it into one of the MV* buckets has some advantages. It can help developers get more comfortable with its apis by making it easier to create a mental model that represents the application that is being built with the framework. It can also help to establish terminology that is used by developers.

Having said,I’d rather see developers build kick-ass apps that are well-designed and follow separation of concerns,than see them waste time arguing about MV* nonsense. And for this reason,I hereby declare AngularJS to be MVW framework – Model-View-Whatever. Where Whatever stands for “whatever works for you”.

Angular gives you a lot of flexibility to nicely separate presentation logic from business logic and presentation state. Please use it fuel your productivity and application maintainability rather than heated discussions about things that at the end of the day don’t matter that much.

在文中特别指出angular在多次的API重构和改善,它越来越接近于MVVM模式,$scope可以被认为是ViewModl,而Controller则是装饰、加工处理这个viewmodel的JavaScript函数。作者更希望大家关注于实现一个成功的,具有好的设计以及遵循“分离关注点”原则的应用程序,而不是去争论MV*,所以他将angular称为MVW框架,是什么并不重要,只要适合你的应用就行。

MVVM模式是Model-View-viewmode(模型-视图-视图模型)模式的简称,其最早出现在微软的WPF和Silverlight框架中。MVVM模式利用框架内置的双向绑定技术对MVP(Model-View-Presenter)模式的变型,引入了专门的viewmodel(视图模型)来实现View和Model的粘合,让View和Model的进一步分离和解耦。MVVM模式的优势有如下四点:

  1. 低耦合:View可以独立于Model变化和修改,同一个viewmodel可以被多个View复用;并且可以做到View和Model的变化互不影响;
  2. 可重用性:可以把一些视图的逻辑放在viewmodel,让多个View复用;
  3. 独立开发:开发人员可以专注与业务逻辑和数据的开发(viewmodel),界面设计人员可以专注于UI(View)的设计;
  4. 可测试性:清晰的View分层,使得针对表现层业务逻辑的测试更容易,更简单。

下面是angular中关于MVVM模式的运用:

在angular中MVVM模式主要分为四部分:

  1. View:它专注于界面的显示和渲染,在angular中则是包含一堆声明式Directive的视图模板。
  2. viewmodel:它是View和Model的粘合体,负责View和Model的交互和协作,它负责给View提供显示的数据,以及提供了View中Command事件操作Model的途径;在angular中$scope对象充当了这个viewmodel的角色;
  3. Model:它是与应用程序的业务逻辑相关的数据的封装载体,它是业务领域的对象,Model并不关心会被如何显示或操作,所以模型也不会包含任何界面显示相关的逻辑。在web页面中,大部分Model都是来自Ajax的服务端返回数据或者是全局的配置对象;而angular中的service则是封装和处理这些与Model相关的业务逻辑的场所,这类的业务服务是可以被多个Controller或者其他service复用的领域服务。
  4. Controller:这并不是MVVM模式的核心元素,但它负责viewmodel对象的初始化,它将组合一个或者多个service来获取业务领域Model放在viewmodel对象上,使得应用界面在启动加载的时候达到一种可用的状态。

View不能直接与Model交互,而是通过$scope这个viewmodel来实现与Model的交互。对于界面表单的交互,通过ngModel指令来实现View和viewmodel的同步。ngModelController包含$parsers和$formatters两个转换器管道,它们分别实现View表单输入值到Model数据类型转换和Model数据到View表单数据的格式化。对于用户界面的交互Command事件(如ngClick、ngChange等)则会转发到viewmodel对象上,通过viewmodel来实现对于Model的改变。然而对于Model的任何改变,也会反应在viewmodel之上,并且会通过$scope的“脏检查机制”($digest)来更新到View。从而实现View和Model的分离,达到对前端逻辑MVVM的分层架构。

angular中MVVM模式的实现,以领域Model为中心思维,遵循“分离关注点”设计原则,这也是与jQuery以DOM驱动的思维所不同之处。所以我们在做angular开发的时候应该谨记下面几点:

绝不要先设计你的页面,然后用DOM操作去改变它

在以往的jQuery开发中,我们会首先设计页面DOM结构,然后在利用jQuery来改变DOM结构或者实现动态交互效果。因为jQuery是为DOM驱动而设计的,对于拥有大量复杂的前端交互的项目,JavaScript的逻辑变得越来越臃肿,交互逻辑分散各处。

在MVVM模式下的angular开发中, 我们首先需要在脑子里挂着Model的弦。不能老想着“我有XXX这个DOM,我希望让它做XXX这种动态效果”,我们需要从要完成的目标开始思考我们需要或拥有怎么样的Model数据,然后设计我们的应用, 最后才是设计视图,并用$scope来粘合它们。

Directive不是封装jQuery代码的“天堂”

如上条所述,我们不能一开始就去想如何利用DOM操作的方法去实现应用目标,然后“冠冕堂皇”的写上一堆jQuery的代码,并将其封装到angular的directive中,最后不得不加上$scope.$apply()来通知angular你的viewmodel的改变,需要启动“脏检查机制”来更新你的改变到View。作者在多个客户项目中看见这种将Directive作为封装jQuery代码“天堂”的例子,其实对于这类问题,大部分情况下,我们都可以用很少了angular代码将其重构为真正的angular way。特别在ng社区经常看见在angular directive中利用jQuery的on方法绑定click、keydown、blur等事件的代码,大部分情况我们都能以对应的ng事件(ngClick、ngChange、ngBlur)来重构它们。

对于这类问题,首先我们应该尽量尝试复用angular的内置指令,以真正的angular way去思考我们的问题,请慎重的引入jQuery的DOM方法和操作。

关于angular MVVM模式的资料,你还可以参考视频:https://frontendmasters.com/courses/angularjs-mvc-mvvm-mvwhatever/#v=ypur7bfbcq。


作者:破狼
出处:http://www.cnblogs.com/whitewolf/
本文版权归作者,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。该文章也同时发布在我的独立博客中-个人独立博客、博客园--破狼和51CTO--破狼。

angular中的MVVM模式 赞,运作原理的更多相关文章

  1. Swift教程17-淡化MVC,使用MVVM框架开发轻巧便于维护的iOS/android app

    MVVM是微软提出一种移动开发框架,旨在针对传统的MVC框架,解决传统的MVC框架的控制器的臃肿问题.M:Model模型,也就是数据模型;比如一条微博,对应的所有字段合成一条微博整体,这个整体就是ModelV:View视图,只用来显示的视图,如iOS的UIView,Cell;当然在iOS中Storyboard中,view总是和控制器关联,这并不是严格的view如果我们纯手写代码定义一个view那么

  2. Swift 2.0 下面向协议的MVVM架构实践

    本文由CocoaChina译者lynulzy翻译原文:Swift2.0:Protocol-OrientedMVVM自从令人兴奋的[《面向协议的编程方法》]在Swift的WWDC大会上发布以来。我已经在之前的博客中使用过MVVM架构,如果你想了解更多MVVM相关知识请参考[这里]。接下来我将讲解,如何添加面向协议。switchToggle.onTintColor=switchColorself.onSwitchToggleHandler=onSwitchToggleHandler虽然在这种情况下看起来并不是

  3. Swift教程17-淡化MVC,使用MVVM框架开发轻巧便于维护的iOS app

    overridefuncawakeFromNib(){super.awakeFromNib()}overridefuncsetSelected{super.setSelected}/***配置Cell的内容方法*/funcconfigCellWithStatusModel(model:StatusModel!){self.imageView2.setimageWithURL;background-color:inherit">placeholderImage:UIImage)self.textLabel2

  4. Swift开发黑科技:还在争论MVC和MVVM?现在你应该试试MVP!

    我下定决心重构自己的代码,下面步入正题,结合Swift开发大会的一些分享,让我们谈谈架构。现在数据工程里面的目录是这样的:模型代码:为了简单我都使用了String类型的数据,至于为什么要使用struct而不使用class,大家可以参考WWDC2015的414号视频,讲的非常清楚,我自己的项目中的数据模型已经全部转成struct了,我会在后面专门写博文讲解struct,这里就不赘述了。

  5. MVVM 不是那么好

    我觉得MVVM是一种反人类的设计模式,它使架构更加混乱而非清晰。MVVM命名很糟糕名称是很重要的。ViewModel这一名称则没有发挥任何作用。ViewModel的第一种含义是modelfortheview。MVVM引进太多职责命名不够具体,导致这个类的任务无休止地增长。MVVM不改变你的架构viewmodel并不能从根本上改变你的应用程序的架构。我能想到的MVVM模式最大的好处就是它把“下水道”从苹果自带的viewcontrooller类转移到了viewmodel这一自定义的对象。

  6. Swift学习第十一枪-基于协议的MVVM模式的实现

    下面是我的新建的Swift学习交流群,欢迎大家一起来共同学习Swift。不管是IOS还是Android,就三种常用模式,MVC,MVP,MVVM网上的资料非常之多,对于MVVM大家估计都有所了解,我在这里就简单的以图示的形式给大家展示。

  7. 关于MVVM的理解

    MVVM中VM到底是个什么角色?MVVM简介关于MVVM,相信大家或多或少都有了解。引用MVVM介绍文中一图受MVC或MVP架构的影响,对MVVM最初印象以为这是一个以viewmodel为核心,处理View和Model的开发架构。于是乎在原有MVC的基础上,创建了一个所谓的viewmodel对象,然后把ViewController中的代码移到viewmodel中,在viewmodel里面处理View以及Model的所有逻辑。完整结构如图所示Model并不表示ModelMVVM架构中的M,并不表示Model

  8. 开发Swift iOS应用程序“正确的方式”

    最近,我学习了Swift和开发iOS应用程序的基础知识。现在,我想自己开发一个真正的应用程序,但我非常关心编写好的代码,所以我已经寻找“最佳实践”,“设计模式”和“正确的方式”来实现它。在我的搜索中,我发现这个greattutorial关于SwiftiOS应用程序中通常使用的所有设计模式,以及他们使用的示例。不应该将httpClient和persistencyManager声明为协议,然后HttpClient和PersistencyManager类实现该协议?我应该在哪里告诉应用程序?最后但并非最不重要的

  9. Android Studio是否支持用于Android UI设计的AngularJS?

    我对AndroidStudio有疑问:AS在设计XML文件时是否支持AngularJS代码,例如:对于小动画或效果?

  10. android – 如何使用ClientID和ClientSecret在Phonegap中使用Angularjs登录Google OAuth2

    我正尝试使用Angularjs(使用IonicFramework)通过GoogleOAuth2从我的Phonegap应用程序登录.目前我正在使用http://phonegap-tips.com/articles/google-api-oauth-with-phonegaps-inappbrowser.html进行登录.但是当我使用Angular-UI-RouterforIonic时,它正在创建非常

随机推荐

  1. Angular2 innerHtml删除样式

    我正在使用innerHtml并在我的cms中设置html,响应似乎没问题,如果我这样打印:{{poi.content}}它给了我正确的内容:``但是当我使用[innerHtml]=“poi.content”时,它会给我这个html:当我使用[innerHtml]时,有谁知道为什么它会剥离我的样式Angular2清理动态添加的HTML,样式,……

  2. 为Angular根组件/模块指定@Input()参数

    我有3个根组件,由根AppModule引导.你如何为其中一个组件指定@input()参数?也不由AppModalComponent获取:它是未定义的.据我所知,你不能将@input()传递给bootstraped组件.但您可以使用其他方法来做到这一点–将值作为属性传递.index.html:app.component.ts:

  3. angular-ui-bootstrap – 如何为angular ui-bootstrap tabs指令指定href参数

    我正在使用角度ui-bootstrap库,但我不知道如何为每个选项卡指定自定义href.在角度ui-bootstrap文档中,指定了一个可选参数select(),但我不知道如何使用它来自定义每个选项卡的链接另一种重新定义问题的方法是如何使用带有角度ui-bootstrap选项卡的路由我希望现在还不算太晚,但我今天遇到了同样的问题.你可以通过以下方式实现:1)在控制器中定义选项卡href:2)声明一个函数来改变控制器中的散列:3)使用以下标记:我不确定这是否是最好的方法,我很乐意听取别人的意见.

  4. 离子框架 – 标签内部的ng-click不起作用

    >为什么标签标签内的按钮不起作用?>但是标签外的按钮(登陆)工作正常,为什么?>请帮我解决这个问题.我需要在点击时做出回复按钮workingdemo解决方案就是不要为物品使用标签.而只是使用divHTML

  5. Angular 2:将值传递给路由数据解析

    我正在尝试编写一个DataResolver服务,允许Angular2路由器在初始化组件之前预加载数据.解析器需要调用不同的API端点来获取适合于正在加载的路由的数据.我正在构建一个通用解析器,而不是为我的许多组件中的每个组件设置一个解析器.因此,我想在路由定义中传递指向正确端点的自定义输入.例如,考虑以下路线:app.routes.ts在第一个实例中,解析器需要调用/path/to/resourc

  6. angularjs – 解释ngModel管道,解析器,格式化程序,viewChangeListeners和$watchers的顺序

    换句话说:如果在模型更新之前触发了“ng-change”,我可以理解,但是我很难理解在更新模型之后以及在完成填充更改之前触发函数绑定属性.如果您读到这里:祝贺并感谢您的耐心等待!

  7. 角度5模板形式检测形式有效性状态的变化

    为了拥有一个可以监听其包含的表单的有效性状态的变化的组件并执行某些组件的方法,是reactiveforms的方法吗?

  8. Angular 2 CSV文件下载

    我在springboot应用程序中有我的后端,从那里我返回一个.csv文件WheniamhittingtheURLinbrowsercsvfileisgettingdownloaded.现在我试图从我的角度2应用程序中点击此URL,代码是这样的:零件:服务:我正在下载文件,但它像ActuallyitshouldbeBook.csv请指导我缺少的东西.有一种解决方法,但您需要创建一个页面上的元

  9. angularjs – Angular UI-Grid:过滤后如何获取总项数

    提前致谢:)你应该避免使用jQuery并与API进行交互.首先需要在网格创建事件中保存对API的引用.您应该已经知道总行数.您可以使用以下命令获取可见/已过滤行数:要么您可以使用以下命令获取所选行的数量:

  10. angularjs – 迁移gulp进程以包含typescript

    或者我应该使用tsc作为我的主要构建工具,让它解决依赖关系,创建映射文件并制作捆绑包?

返回
顶部