把两个框架都过了一下:
Angular:简洁,容易入门,代码量少,但背后做了很多事,觉得不好把控,对脏检查也不是很认同 Ember:结构清晰,跟 rails 结合更好,官方文档更清晰,但代码量大
你们是怎么选择的?
我一直看好 ember…可能是因为我接触的第一个 rails 应用是 discourse…用 ember 的……但唯一一直怨念的就是 ember 不能用 coffee 写似乎…
#5 楼 @cassiuschen 虽然我是个 CoffeeScript hater 但是我还是想好奇问一句:Ember 哪里有限制不能用 coffee 写么?貌似看 discuss.emberjs.com 上好多用 coffee 做例子的,RailsCast 那边教程里也是 Coffee 走起。。。
谷东歌不缺高手,鼓捣出来一个新玩意跟玩儿是的,扔掉一个旧玩意跟扔张手纸似的,并且谷歌很会造势,每当推出个新玩意媒体铺天盖地的造势,打几杆发现没枣就扔了不管不问了。这几年每过一段时间谷歌都会弄出来一个"革命性""颠覆性的东西调戏码农,咋呼几声就没下文了,码农还没跟上,谷歌又在鼓捣下一个革命性的东西了
根据自己使用各种 Framework 的经验,我建议你分别研究一下 Angular 和 Ember 的源码,然后自己来感觉到底哪个 Framework 的源码自己能够把握,出现问题如果文档上没有,且 google 不到的话,可以自行深入源码去解读,就选哪个。
讨论好像朝着奇怪的方向发展了……
#1 楼 @boyishwei Ember 的文档还挺好的,看了之后基本掌握了,很标准的 MVC 模式,所以没有太大难度。 反观 Angular,看完文档都不知道说啥
我两个文档都啃了两次,动手的时候发现一个问题:为什么要把一个应用拆成两个徒增代码量,所有变量传递都改成 API?
后来 DHH 写了 SJR 那篇文章(http://37signals.com/svn/posts/3697-server-generated-javascript-responses),我发现 Basecamp 方案就是我要的。
Angular 把我所有用过的经验加上也就 2 个月,不算高手,就不评价了。
Ember 我想我还是有发言权的。从不到 1.0 版开始跟起,1.0 刚出就用进项目中(大概去年 8 月)一直到现在,并且 web app 和 mobile app 都用过。对框架的理解程度自认算中级水平。
技术比较之类的太多了。我就不细讲了,网上文章很多。有心可以去 Google。
我觉得 Ember 最大的优势,不在于结构清晰,跟 Rails 结合好,从各种工具函数到常用 mixin 无所不包……而是在于自 1.0 以来快速稳定的发展速度,持续的创新精神和活跃的社区。这点很像 Ruby 社区的氛围。总有新东西冒出来,然后作为 best practise 并入框架之内。
这也是我有信心它以后会变得越来越好的前提。虽然目前还有不完善的地方。但就我用过的 Backbone, Angular, Ember 三个框架来说,没有一个达到了完善的程度,或者说整个前端 MVC 都仍在摸索中。
Ember 自 1.0 版后每六个星期更新一次,目前已经到了 1.3,每次 release 都会有若干 feature(不完全是小修小补),1.2 加入了 loading/error substate,1.3 加入了大幅改进的 RSVP 并完善了文档。还有 query parameter 这种已经实际可用,但为了保险仍在 canary 分支中测试的 feature。
今年将会有几个重大改进:具体细节可以看看 What's coming in Ember in 2014 。基本上,我对 Ember 比较不满的地方都会在今年得到弥补,而且会解决的比较完美。
如果你想做一个产品,Angular 和 Ember 基本都能满足你的需求。这方面两者提供的特性不相伯仲。相比而言我觉得“哪个框架不适合做什么”更重要。实际使用中,Ember 作为一个大而全的框架,没有明显的短板。但仍然有不够好的地方。
Handlebars 和数之不尽的 script 标签
Ember 的 binding 没有 Angular 那么高性能,而且 Handlebars 对 if, each 之类的绑定都会生成 script 标签帮助定位,所以页面复杂后生成的 dom 数量不少。这点在 web 端感觉不到性能差距,在 mobile 上一般页面也还可以接受,但对于很长的列表和各种 input 比较多的 form,在进入页面是就能感到明显的停顿,因为需要花时间 render template。
这点可以通过减少双向绑定的元素来解决。适当使用 unbound,each 中可以使用 group,或者删掉滚动到屏幕区域外的 view(Discourse 的 ember-cloack)就是用来做这个事情的。
今年 Ember 准备用 HTMLBars 替换 Handlebars 来获得更高的模板引擎性能,根据现在的测试,双向绑定的性能直逼纯 JavaScript 修改页面 ,而且额外的 script 标签也都消失了。而且还让 Ember 可以在 template 中写类似 Angular 的复杂表达式,不再局限于只绑定某个属性了。
Ember Data
没有一个好的 Data layer 是 Ember 绕不过去的坎,Ember Data 一直在开发中,其他的替代品如 Ember Model, EPF 各有擅长,但缺点也同样明显,不大适合用在产品环境中。Angular 的 $resource 虽然也不给力,但还有 Restangular 撑大梁。
在 Ember Data 完工之前,甚至是完工以后,我都推荐用 Em.Object 和 $.ajax 自己封装 model。这样可以根据需求做到最大的灵活性。实际使用中没什么困难,也没什么问题。Discourse 那么复杂,也是用这种方法做的。
对于喜欢类库的人,今年有个 Ember 社区衍生出来的类库 Orbit.js 倒是可以期待一下。功能还比较强大。而且上升势头非常猛,上星期我看了下 star 才几十,今天已经到 600+ 了。可以看看这篇 slide:Introducing Orbit.js 。
Animation
Ember 到目前为止,实现 Angular 那样的 animation 都不现实。目前只有一个 animated outlet。Angular 的 animation 已经细化到连 ng-if 都有 animation 了。这点确实很赞。
目前只知道 animation 也是 Ember 今年的重要目标之一,虽然目前还没有成型的 API,但我相信最终公布时,会有一个完善的解决方案。这是 Ember 引入新功能一贯的标准。其实前段时间有人加入了 animation 的 pull request,但最后因为觉得不好被 revert 掉了……
顺便提提 animation 的性能。我的实际经验中,mobile app 只要使用 -webkit-transform 做动画,是会有硬件直接加速的。流畅程度跟 native app 不相上下。但 JavaScript 控制 style 这种动画就非常卡,所以如果用 -webkit-transform 的话,影响不大。HTML5 构建的 mobile app 慢的主要原因其实是 dom 过多。
总的来说,Ember 我觉得可以作为长期的生产力工具去投资学习。这是一个完全由社区推动,崇尚研究和整合通用的 best practice,并且非常活跃的框架。
最后,大晚上写了这么多,觉得有所收获的给个喜欢吧 :-)
都不用,我用 rivetsjs, 比 ember 和 angular 小多了,no shit, 只做一件简简单单的事:数据绑定,还不需要手写一堆 getter setter
@Rei 如果是有多种客户端(web app, mobile app)这种,server 只当 API 传递 json,web app 用 MVC 就是一个合适的选择。mobile app 如果使用 PhoneGap 的话用 MVC 也是个好方法。
如果只考虑 web app 的话用什么都行,DHH 曾经发过一个推,大概意思就是为什么我们需要 double MVC 共 6 层把事情搞得很复杂。实际使用中我确实感觉到麻烦一些。所以不建议只是为了架构或尝鲜去使用前端 MVC。简单有效的方案就收好方案。
我以前是 ExtJS 重度使用者,感觉 Ember,Angular,Backbone 之类的跟 Ext 里的方式比弱爆了。。。当然,我现在也在使用这些东西
@darkbaby123 可以用 http://www.odata.org/ 将服务器 render 完全弱化,server 只处理 model , validate , permission,scale 此类事情,UI ,是完全不需要 server 来处理的,这样开发其实更简单
@hysios 感觉和 Parse 比较类似。其实把 server API 化也是不用管 UI 的,只用管 resource 和 action 就行。但我一直不喜欢 Parse 的原因之一在于,这种服务简单的把 model 和 RESTful 的 resource 画了等号,面对简单的应用场景没问题,但复杂的地方我觉得还是自己写后端逻辑更好。而且 Rails 本来处理 model, validation 这些就不麻烦。
#13 楼 @gaicitadie 完全同意,google 做算法、工程工具没啥问题,但是做框架、语言会很死板,非常不喜欢
但是。。。最后我的选择还是 Angular,虽然有 DI 等等一系列讨厌的东西,但是整体的思路上先进太多了
期待今年有比 Angular 更“有趣”的框架诞生
@hysios 你没理解我的意思。实际上用 Rails 做 API server 也就是返回 json 而已,不涉及到任何 view & helper 的事情。自然不会有 server render。我举 Parse 的例子只是想说明有些业务逻辑还是自己写更方便。而不是让第三方 API server 托管一切。
@darkbaby123 odata 并不是通过第三插件,而是一个技术标准,是通过 http 实现的一种接口,像是 Rails JSON API 一样,你可以定义自己的输入与输出参数,调用自己定义的 API , 有点像是 servcie over http, 而且还可以 batch api request/response, 这样避免的要拿一个变量,就发出一个请求的这种问题,你可以把许多的数据通过一个请求拿回来,这样避免了 @Rei 所说的 涂增代码与请求数的问题
这年头选择太多了也确实是头疼啊,所以才有了 http://todomvc.com/ 这种奇葩网站. 不过说实在的,todo list 这种简单的应用真的用框架写了也不太能试出来一个框架的痛点。
这两者里面只用过 angular, 投 angular 一票吧。
@Rei @darkbaby123 我同意 darkbaby 的看法,随着现在移动端如此强势的情况下,网页端已经弱化成一种终端形式,后台的 restful 化能够使得架构及其简单实用,非常易于扩展和维护。各个终端开发团队可以并行开发,分别实现最贴近于各自平台的交互和 UI (或者是 hybrid).
Rei 转的那篇文章我觉得思路有些不对,我认为计算力应该往终端移,特别是初创企业,如何减少服务器和带宽使用,就能减少初期投入而增加生存的可能性。
@hysios 这倒是有意思,有时间我去看看。JSON API 的标准确实很有必要。Ember 就自己折腾了一套规范(名字就叫 JSON API),你说的功能像 batch get,batch update,relationship 和 side loading 都有定义。不过还在完善中,某些地方我觉得也不够实用。目前这方面还有一个比较有名的规范 HAL 。
JSON API 和 HAL 这两个都是属于 hyperlink API,我感觉很像把网页的数据直接转换成了 JSON 格式,有数据有链接,如果以后搜索引擎支持的话,完全可以做到搜索引擎友好。也可以避免前端 MVC 动态生成模板导致的 SEO 问题,估计会是以后 API 发展的一个方向。
我在自己的项目中刻意对 backbone、ember、angularjs 三种框架都用了一下,体会如下: 1 做一些简单的表单处理,angularjs 最好用,速度最快,但是面临复杂的情况,就会遇到许多坑,特别是用到 js 做一些特殊处理(例如与 bootsrap 整合,所幸的是,有人已经帮你做好了,各种指令、服务等,不过 semantic-ui 就没有这么幸运了,需要自己写指令和服务)需要自己研究源码,会花费许多时间。 2 bakcbone 本身很简单,但也有许多坑,不过克服了这些坑之后,还算顺利,退一步,即使遇到 backbone 解决不了的,但也可以自己写 plugin,另外,backbone 有 jquery 这个后盾,退一万步,还可以用 jquery。backbone 的缺点是重复性代码比较多,需要考虑许多细节,例如 sub-view,模型绑定等(这个缺点可以通过一些插件解决),比较烦。 3 ember 从表面看起来最优雅,其设计哲学与 rails 有许多借鉴,但这一点同时引入许多其特有的概念不是很好理解,从我自己角度来看,其 model、view、controller 区分的不是很明确,从传统 mvc 角度理解的话,有点变扭。
总结的话,对于不是很熟练的人来说,backbone 风险最小,但比较繁琐。 ember 最优雅,但学习曲线有点抖,不过过了这个坎之后,用 ember 最舒服。 angularjs 也许未来很光明,但现阶段风险比较大。 如果最后到了需要研究源码的阶段,backbone 最好把握,另外两种旗鼓相当,都不是省油的灯
我来说说我的观点,第一,楼主的问题本来就是一个XY problem 。两个都可以说可以,都可以说不可以。帖子没有一点建设性的新意,只会增加初学者的心里负担。
第二,javascript 社区发展很快,但仍然不是很成熟。单独靠它做项目,最最重要的技术还是 javascript,框架都是语法糖,没啥心意。和 Rails 社区比起来,差好几个档次。大家玩技术都是想做的更酷一点。你总不能拿个破车充当奔驰
第三,如果非要做出选择,其实代价也不是不可承受。那就是成为两个框架的 top 10 contributor,不管你投入精力的初衷是不是为了验证哪个框架好,最少你曾经投入过精力去做过。
第四,实际项目选那个都可以,作为专业开发,没有的功能就实现它,有的功能就强化它。说这个坑,那个坑,都是在回避问题,不想解决问题。哪有没有代价的选择呢?
@jeff_duan 随着 web 端越来越重视交互,和浏览器功能的日益强大,前端 MVC 只会发展的越来越好。因为本身就是因为需求导致的前端 js 越来越复杂,才会有人想到加入模式去构造系统。不管从现实世界用户需求的发展还是从技术发展来看,现在已经接近前端 MVC 的黄金时期。
不过传统的 server rendered website 还是不会消失。有些页面像公司主页或者一些宣传页面,结构简单并且各种动画效果做的很酷。这些页面直接 server render page + jQuery 干活反而更快。还是那句话,不同的应用场景使用不同的技术。
@xds2000 第二点和第三点不赞同。JavaScript 社区现在确实不成熟,但并不代表差 Rails 社区几个档次,实际上论创新程度,Github 上的 JavaScript 项目绝对比 Ruby 项目多。因为某些程度上说,不成熟才代表有足够的进化空间。不成熟,但有前景,就更好了。这两点 JavaScript 都符合。而且严格来说 JavaScript 不存在一个统一的社区,这点跟 Rails 没有可比性。拿 jQuery 社区,Angular 社区和 Ember 社区相比还差不多。
框架就是语法糖,换个角度也可以说,Ruby 才是最主要的(这点没错),Rails 就是语法糖,没啥新意(这点没人同意吧)……
学习和使用框架也没必要成为 contributor。如果说每种框架代表一种思想,能跻身进入 top 10 contributors 的都是对框架有不下于原作者理解,并且做出绝大贡献的人。我等使用者能去按照实际情况提几个 feature & bug,发 pull request 修复下 issue 都算是不错了。
@darkbaby123 请注意,Rails 重新定义了 Ruby。但 jQuery,Angular,Ember 都只能玩模式,更本动不了一点 Javascript 的语意。这个差距我说好几个档次都是客气了。但我说个 Javascript 发展比较快,加上 Nodejs 的推动,让它可以理论上替代任何后端技术。但就技术,高大上,这三个维度,都是没法和 Ruby 比 (这里不比较 Rails)。这是现状,但未来如何,还要看业界的大佬怎么看。
学习和使用框架以成为 contributor 为目标,进入 top 10 contributors,都只是姿态。你去试试就会知道,投入的精力非一般人那么轻松。我的意思就是投入,只有投入才可以有产出。投入多少看个人情况了。但“去按照实际情况提几个 feature & bug,发 pull request 修复下 issue”,这都是打酱油的情况,根本提升不了对这个框架的理解。
@xds2000 框架都是基于语言之上的,语言做不到的,任何框架都做不到。Ruby 的灵活性和潜力就摆在那,只是被 Rails 发现并且发挥到一个极致了而已。所以这点上我觉得 Rails 没有“重新”定义 Ruby。
如果从影响力而言,Rails 把 Ruby 从一个小众的语言一下子拉入了大众视野,这确实可以算是重新定义。但是……它只是 重新定义了人们认知中 Ruby 能做的事情 而已。
同样从影响力而言,Prototype 和 jQuery 完全可以说重新定义了人们对 JavaScript 的看法。让人们认识到可以用如此统一的方法解决跨浏览器的问题,可以用 css selector 的语法去操作 dom 树。可以让不擅长编程的设计师都能上手做一做动画效果。这都不算是影响?没有这些基础框架我们现在还在做 if else 去判断 ajax 用 ActiveX 还是 XMLHttpRequest,还在纠结事件绑定该用哪种 API,还在纠结某些特定事件是没有冒泡版本的。没有这些库把底层都统一了,你哪有时间去做高大上的 app?
同理,在 jQuery 做的前端越来越复杂的前提上,Backbone 引入了 MVC 的基本概念来构建前端代码结构,让人们认识到 JavaScript 是能构建前端 app 的“语言”,而不只是到处绑定一下事件写写 callback 的“脚本”,Angular 和 Ember 更进一步让人认识到作为展现和逻辑分离的框架,没必要去手动更新 template,可以让人们更专注于数据。这些都不算进步什么算进步?
如果你觉得 Rails 基于 Ruby 的元编程做了很多的事情,可以在此基础上重新定义 DSL 等等算是重新定义,我只能说语言特性和应用场景不同,不必拿 Ruby 的标准去衡量 JavaScript,反过来也没必要。举个例子,Promise 在 JavaScript 中特别有用,单这一点就可以改变很多地方的编程模式,但在 Ruby 中没得到重视,除开语言特性的不同,在 server 端也有很多其他的方式(比如 background job)去做到异步调用,以一种更适合 server 端的方式。
至于 contributor。我本意只是想表达学习框架跟成为 contributor 没有必然联系。想要作贡献也必须要有非常深入的了解,不然就是添乱。很多使用者都只是跟跟源码,能做到发现 bug 并且打补丁都是进一步的了(框架都不了解谁能去打补丁,酱油也不是这么打的)。真正能做到贡献很大的都是对框架有不下于原作者理解的人。这需要大量的时间和精力去积累。只是学习框架没必要定这么高的目标。自己实际上手用用,看开发理念合不合自己的 style 就行。
@small_fish__ 我就用 Marionette. 当时在 Backbone 和 Ember 之间摇摆,一看到 Marionette 立刻被说服。Marionette 文档虽然很详尽,但在具体实践方面写得没有 Ember 那么直接,例子也没那么多。感觉一定要深入理解 bbclonemail 才能顺利入手。我的观点是 Marionette 各个方面都有覆盖,但比较轻量,很多功能想要可以自己加。
至于 Angular, 我是跟着 Unobtrusive web 一直做上来的。暂时还没法接受直接在 HTML 中写ngclick=()
之类的做法。
@billy @small_fish__ 有空说说 Backbone/Marionette 的经验?很多人对 Marionette 评价很高的样子。
#50 楼 @darkbaby123 关于 Backbone,我甚至不认为它是一个框架,或者说远远达不到一个框架的程度,只能说他是一些可以方便复用的组件库,可以基于这些组件搭建抽象层级更高一点的框架,Marionette 就是这么干的。但是在抽象问题,映射问题,解决问题方面,越是抽象层级越高的框架越方便有利,从这个角度看,Marionette 就完全被 Angular / Ember 甩出去几条街了。
#47 楼 @billy 我在学习 Marionette 的过程中,也发现他很多时候需要反复研读作者的 Blog 上的文章才能理解 Marionette 的设计思想,以及如何才能正确使用 Marionette。
后来公司同事介绍一本书给我,帮我解决了很大的问题,让我在最短时间掌握用 Marionette 构建应用的知识和最佳实践。这本书叫做 Backbone.Marionette.js: A Gentle Introduction 如果需要用到 Marionette 的话,我强烈推荐这本书。
@darkbaby123 我们讨论的话题已经开始跑题,但我还是愿意再回一条,以此来切磋。
“框架都是基于语言之上的,语言做不到的,任何框架都做不到。” 不是我要扣字,只是你没有说清楚到底什么是语言做不到了。我不想胡乱猜测你的想法,但你说的意思好像是说没有 Rails,肯定有其它项目能把 Ruby 的灵活性和潜力发挥到极致?这个我不敢苟同,但多挣这个,在技术讨论上,也不会让我们学到啥,这个只能把我的论点放在这里。
同样从影响力而言,我指的是 Rails -> ruby 语言这个方向。通过 Rails core lib 转化到 ruby core lib(再 ruby 1.8 -> ruby 1.9 期间),这个就是影响。但 jQuery, Angular 和 Ember -> javascript 语言的影响更本就不存在,并没有那个技术能被 Javascript 标准所采纳。大家只能服从,模仿,兼容 javascript 标准。加上浏览器引擎对 spec 的理解又不相同,实现上更多的坑等着开发者。
"如果你觉得 Rails 基于 Ruby 的元编程做了很多的事情,可以在此基础上重新定义 DSL 等等算是重新定义,我只能说语言特性和应用场景不同,不必拿 Ruby 的标准去衡量 JavaScript,反过来也没必要。" nodejs 都把后端全做了,这还有什么不能比的。ruby 能做的,javascript 也都能做。这个业界的产品都有参考物。作为技术,咱们不比语言特性比什么?应用场景我说的都是和 Web 相关的,不靠谱其他,但加上 nodejs 后,没有什么场景是 javascript 不能用的。反过来,javascript 能做的,ruby 也能做,最多转换一下。比如https://github.com/xxuejie/webruby。这个扯远了,我的观点就是现在 ruby 和 javascript 是可以放在一个台面来比的。
至于 contributor,这个每个人的学习方式不同,可以 ignore 我的观点。不用讨论这点。
@veggie,Spinejs 我也喜欢,可惜应用实例不是很多,所以没用过。Spine 的作者写过一本 Object Oriented Javascript, 感觉非常不错。
@small_fish__ @darkbaby123 , 同感,喜欢自由。不敢说经验,只觉得好用,够用。关键是掌握 sub apps 和 components. 另外,广泛应用 resreq 太重要了。不过现在 Stackoverflow 上面 Marionette 非常少人问问题,反观 Angular 一大把,不解。
@small_fish__ , this one https://github.com/marionettejs/backbone.wreqr, Extracted from Marionette to decouple modules. The pattern App.request
, App.vent
is very useful in my opinon. Allow me to reply in English as Pinyin is buggy on Opera in Ubuntu.
@xds2000 说到框架是基于语言之上,我想说的是,任何框架都是在语言之上构建的,他们可以最大地挖掘语言的潜力,但没法做到语言做不到的事情。所以从语言特性上说,没有框架可以重新定义新的语言特性。 举个栗子,客户端 JavaScript 都是跑在浏览器的沙箱之内的,而且有严格的限制,比如 website A 的 JavaScript 读不到 website B 的数据,或者操作浏览器之外的资源(外加 ActiveX 这种插件的另当别论)。 我也并没有表达“如果没有 Rails 也会有其他框架诞生去挖掘 Ruby 的潜力”的意思。就像谁也不知道当年牛顿如果被苹果砸死了会不会导致物理学晚发展一百年。这种事情没有定论。
从影响力而言,Rails -> Ruby 的影响力确实存在。其实两者是相辅相成的,框架不能直接去修改语言特性,但可以通过提倡 best practice 去影响语言设计的趋势。Rails 大量用 hash 模拟可选参数,因为这种编程方式用的多了,到了 Ruby 1.9(忘了是 1.9 还是 2.0 了)有了内建的可选参数机制。与此相类似的还有 concern。很难说 Ruby 是不是受了 Rails 的影响。反过来说,从语言层面有了更好的支持,框架才可以以此为基础走的更远。
JavaScript 也有类似的情况。只是不是由一个框架说了算的。更类似于每个 lib 或 framework 产生一些新的点子。因为 JavaScript 从开始到现在都没有诞生过一个占统治地位和指导思想的框架。原因说起来很复杂,我觉得不仅仅是语言灵活度的因素,还有浏览器不一致的因素。
但这种语言和框架互相促进的情况也是有。实际上 ES 5 和 ES 6 的规范,都是基于现在人们碰到的问题而设计的。而不是先设计好标准然后框架坐等实现。举个栗子,ES 6 module 是为了从语言层面上提供模块化的功能。设计的原因在于模块化这玩意后端以 CommonJS 为主,前端以 AMD 为主。没有个统一的规则。但 ES 6 module 的语法现有的浏览器又不支持。怎么办呢?有人开发了 ES 6 transpiler 去把 ES 6 module 语法编译成 AMD 或 CommonJS 的语法。浏览器不支持的时候就先这么用着,等支持了再作处理。
与此类似的还有 observer,web component 等。我想说的是,前端这一块不仅仅是有人定规范,然后各家框架都去遵守,框架的发展也会推进或改变标准化的定义。
太晚了,瞌睡来了先写这些。
@lgn21st 高层抽象确实用的舒服,但也会带来更多的约束。选择一个框架,就得接受它所有的优点和缺点。我想直到现在还有不少人选择 Backbone/Marionette 或者类似的框架,也是因为可以有更大的自由度。
Angular 能获得现在如日中天的地位,也是类似的原因。它其实更类似于一个提供了关键 feature 的基础设施。不同的使用者能基于它,结合自己的业务逻辑去做自己的框架。按作者的话说:Angular is not a framework, it's an HTML compiler. 所以我一直觉得它的 killer feature 不在于 dependency injection, service 和 data binding,而在于 directive。
BTW 我一般不喜欢看框架比较的文章,但这篇 slide AngularJS from an Ember.js perspective 确实不错。它从设计哲学上分析了为什么两个框架会发展成现在的样子。我觉得不管用不用 Angular/Ember 的都值得一看。
我选 angularjs,现在的理由是框架本身下载大小差不多已经是移动客户端的可接受极限了,Ember.js 的250kb+ 初始下载真的不可接受啊。。。
#50 楼 @darkbaby123 之所以很多人对 Marionette 评价很高,是因为 backbone 本身做的有点差,连最低层的视图刷新、内存管理都需要用户自己做 (想象一下,一小部分数据改变,你需要手动刷新整个视图),Marionette 弥补了这些缺陷。我倒是觉得 backbone+Marionette =ember,我很赞赏 ember 对视图刷新这部分的处理(特别是被 backbone 蹂躏过的人来说),读一下:http://emberjs.com/guides/understanding-ember/the-view-layer/上面的文章就知道了。
backbone 太低层了(基本上是 jquery 的一个方便的包装器,不过反过来说,正因为这样,风险最小,jquery 大街上一抓一大把,许多问题社区都有解决方案)。
#65 楼 @darkbaby123 看了这篇 slide 单从语法上 ember 对我来说更舒服一些。 顺便问个问题 slide 里面有“How Angular Embraces Plain ol’JS” , “How Ember Ditches Plain ol’JS”,ol'js 怎么翻译呢
其实支持哪个框架要好没多大意义了,用得好才是重点,做的东西好了用户不会关心你拿什么做的,ember 和 angular 现在都是可以产生生产力的框架,我觉得这个看项目组实际情况来决定用哪个就好了,其实学起来都不难,还有就是个人喜好,我个人是比较喜欢 ember 这种了,我觉得 ember 目前被接受程度不高的原因是文档还是写的不够详细,例子也不多,实际上如果你真的用心去学习了 ember 一定不会让你失望的。还有高手们应该多愿意给大家分享下自己的成果,这样会有助于技术的普及,当然分享在国内也是个问题,小白程序员提问的素质也比较差点。
用过一阵子 AngularJS,一开始觉得很高兴,后来各种不清楚跟性能问题搞到很失落,总得感受是入门不难,但是高阶有难度,总感觉没把握。 最近开始使用 ractivejs,感觉很清爽,个人会推荐用这个多些。
angular.
入门没那么简单,但是绝对是顶级框架。
比较几个框架的时候,看看关注的人数。另外 stackoverflow 搜一下。很多帖子的。
不过要是快速开发,还是先 rails 吧。
我更喜欢 EmberJS 首先在 Ember 里面可以看到更多 Ruby 的影子 其次 Ember 已经是 JS MVC 的集大成者,用起来比 Backbone 要方便,但又比 Angular 透彻 不可否认,Ember 还有很多缺点,譬如与生成 DOM 的 jquery 插件集成度不好,handlebar 的使用导致会出现大批的标记,但我对 Ember 的未来比较有信心。
个人感觉任何一个框架 粉丝们都能罗列一堆优点 然后那?好的宣讲者还应该罗列出自己遇到的缺点 或被虐的经历 然后 (准) 使用者们权衡一下能不能接受这些弊端,这样结果就出来了。
可能有人说我消极,但我还是坚信:Nothing is perfect
js 已经统治世界了。。。。因为 web 已经统治世界了。 想想还真是,约定一个容器,把标准放出,就是相当于一层开源免费的虚拟机啦,完全隔离了操作系统的不同,更不用说底层的硬件了。在这个免费开放的标准之上,我们构建出缤纷的 GUI 世界。 web 已经统治世界了。。。
#16 楼 @darkbaby123 请问怎么用 Em.Object
来自己封装 Model 呢?我用 ember data 实在用不下去了,可是我在网上搜,对于用Em.Object
怎么自己封装 Model 的文章实在少的可怜,有没有什么代码可以介绍一下呢?Discourse
看到不他的Discourse.Model
是哪里跑出来的。
@QueXuQ 我也是很简单的封装了一下。单个 model 用 Em.Object,集合有些是仿照 Backbone 的做法封装 collection。更简单的地方就直接是 $.ajax 了。举个栗子:
比如单个 model
App.Task = Em.Object.extend
isNew: (->
not @get('id')
).property 'id'
# Common methods, like create and update
save: ->
if @get('isNew')
url = "/api/tasks.json"
method = 'POST'
else
url = "/api/tasks/#{@get('id')}.json"
method = 'PUT'
$.ajax(url: url, type: method, data: @paramsForSave()).then(
(payload) =>
@setProperties(data.user)
(xhr) =>
@setProperties(xhr.responseJSON.user)
)
# Custom method, finish task, submit to "/api/tasks/1/finish.json" (PUT)
finish: ->
$.ajax(url: "/api/tasks/#{@get('id')}/finish.json", type: 'PUT')
paramsForSave: ->
# generate params
# class methods
App.Task.reopenClass
_findAll: (params) ->
modelClass = @
$.get("/api/tasks.json", params).then (payload) ->
payload.tasks.map (obj) -> modelClass.create(obj)
findAll: (params) ->
App.PromiseArray.create promise: @_findAll(params)
find: (id) ->
# find a single object
App.PromiseArray = Em.ArrayProxy.extend Em.PromiseProxyMixin
使用方法:
tasks = App.Task.findAll(finished: false)
# Before data is resolved
tasks.get('firstObject') # => null
# After data is resolved
tasks.get('firstObject') # => an <App.Task> object
这个例子做了一些简化,只是为了解释思路。大概就是把 $.ajax
封装成方法方便调用,至于为什么把 json 用 App.Task 封装起来,是为了用 computed property 构造更多的虚属性,或者实现一些 model 相关的逻辑。
虽然 Ember Data 碰到实际需求不怎么好用,但它的代码还是很值得一看的。比如:
如果觉得麻烦,那就用 Ember Model 或者 EPF,不过我觉得他们也只是比 Ember Data 更轻量,碰到问题更容易扩展,其实也没那么灵活。
#90 楼 @darkbaby123 Ember Data 可以声明 model 属性之类的方法确实把 Model 做的更接近 M 这一层,可是 Ember Data 的文档实在太少了,遇到问题后需要花非常多的时间进行解决,而且不知道如何扩展,源码看过一点,实在太多了,无法清晰的理解。
估计还得先看看 ember model 的源码,就几百行而已。
看了你用 Ember Object 写的源码后,比较清晰怎么用 Ember Object 来写 Model,我试试看看。但是有个地方不是很理解,就是:
$.ajax(url: url, type: method, data: @paramsForSave())
paramsForSave: ->
# generate params
这个要做的是处理参数的形式,例如把userId
转为user_id
,还有拼接等等?
@QueXuQ 嗯,建议自己写的时候不要做 camelcase 和 underscore 格式的转换,因为这意味着你要处理两种逻辑:
往往一个简单的赋值就要变成写循环去转换 key,多了一堆代码,而且处理不慎会比较容易出错。
所以我对 model 字段名都是用的 underscore 格式。不和谐就不和谐吧。
#92 楼 @darkbaby123 确实,我也不打算做转换了。直接能用 underscore 的地方就用 underscore,就好了。 麻烦我想问问,你有什么拼 params 的好方法吗?我直接是:
paramsForSave: ->
user =
name: @.name
email: @.email
{user: user}
我觉得我这样做比较死板。不知道有没有什么优雅的方法呢?
最简单的做法:
keys = ['attr1', 'attr2', 'attr3'];
params = @getProperties(keys)
# 对不存在的 key, getProperties 会返回 undefined
# $.ajax 会把所有值为 undefined 的 key 忽略,所以要把 undefined 全部转成 null
params[key] = null for key in params when params[key] == undefined
params
#68 楼 @xwf286 backbone.model + rivets 倒是可以减少很多刷新的代码,以至于我连状态都用 model + rivets 来处理了,View 层再也不用写 toggleXXX,addXXX,removeXXX 了。
backbone 胜在上手,没有多余的概念。用来构建自己的一套 framework 也非常简单。但是也如其名,只是一个 backbone 罢了。其余的两个在摸索架构上面还是不建议使用,毕竟一用,感觉就有点定型了。
ember 让我抛弃的原因最关键的也就 handlebars 编译之后过于庞大,View 实现刷新的代码实在丑陋。
AngularJS 的问题是如果要实现一套对等的 API 难度过大,架构和概念上有点不利于新手上手,二来 Google 的东西有点信不过,容易被抛弃的感觉。
#98 楼 @darkbaby123 恩。关键我看 Ember Data 现在的更新速度,要完成估计需要很长的时间了。 关于 model 层这个设计,我有个疑问我想请教一下你。 Ember Data 的删除设计是这样的:
@content.deleteRecord()
@content.save()
而我写的是直接就 deleteRecord():
deleteRecord: ->
$.ajax(url: "/api/products/#{@get('id')}.json", type: "DELETE")
然后跳到首页,数据重新加载了,就直接没有了。这样的设计不知道有没有什么缺陷呢?
喜欢 backbone 的 non-opinionated nature,可以让我随时都有掌控权。 对于大一些的 backbone,我认为 marionette 在构建大型可维护的前端应用的 best practice 和 patterns 很实用。 现在的前端开发跟软件开发越来越接近,所需要的 tools,design patterns 也越来越多。花更多的时间去了解自己的设计架构比去了解一个 framework 的内部运行重要的多。backbone 在这点上很赞。
@QueXuQ 我对 ED 用的也不是很多,但 ED 这种客户端 model 层都有种客户端缓存的概念,deleteRecord 是删除客户端 record 可能只是改变状态,让你在客户端能过滤掉这个数据,save 把改变同步到服务端去。
这个没所谓哪种 pattern 更好,看你的实际需要而定。
@coderek 这就是各个框架的设计哲学了。Ember 就是 strong opnionated 的。作者认为对 web 开发而言,有很多架构问题是大部分 web app 都会遇到的,而“常见的问题需要通用的解决方案”,避免开发者在什么才是最好的构架方式上纠结从而浪费时间。marionette 仅仅提供的是点,而不是面,Angular 则只提供地基。但这没什么不好,如果开发者很清楚自己在做什么,有自己的一套架构,那么选择灵活性高的框架是更适合的选择。