@xds2000 RJS 是很早以前(Rails 3 以前)Rails 推出的用 Ruby 写 JavaScript 的方法,完全是 Ruby 代码
举个栗子:
# some_view.rjs
page['time_updated'].replace_html Time.now
page.visual_effect :highlight, 'the_list'
这段代码是从 这篇 ITEye blog 上摘抄的,看看日期你就知道有多古老了。
Rails 会把这一段代码渲染成 JavaScript,当时还是使用的 Prototype。年代太久远记不清楚了,大概是这个样子:
$('time_update').replace('some time');
$('the_list').visualEffect('highlight');
这种技术非常依赖前端的 JavaScript 库,而且也不够直观。只不过算是一种“用 Ruby 写任何东西”的理念的衍生物。
后来在 Yehuda 把 RJS 移除了(貌似是 Rails 3 时代?),换成了 js.erb 的方式,直接在 view 里面写 JavaScript。这就是 DHH 文章里面说的 SJR(Server generated JavaScript Responses)。
@Victor 如此本土化的翻译,完美表达了 DHH 的嚣张样~
这跟气度和潮流无关,Rails 本质上还是 server side 的解决方案,走的还是服务端处理大部分逻辑的路子。这种情况下某些 ajax 请求返回 html + js partial 确实比直接返回 json 更好。不需要一套 template 分别用 erb 和 js 实现两份(尤其是 template 中含有数据格式化的,更蛋疼)。可以最大程度的重用代码,易于维护,也方便打 cache。
照 SJR 的思路发展,turbolink 的出现就是一种必然了。对不是非常重客户端交互的应用来说,Rails 提供的这种解决方案还是挺好的。提供一定的动态交互的同时最大限度的利用 Rails 在 view 那一层优势。
但如果用前端 MVC 的话,因为 template 的逻辑都在客户端,这时候 json 就是最好的选择。因为 server 已经完全没有必要关心数据怎么展示的问题了。
总之,一件事情,要么前端做,要么后端做。两边都做 50% 的话非常夹生…… 如果两边都做 100% 那就蛋疼了。
赞一个,Github Styleguide 也不错。问一下,当 html 不是很多的时候,那些 css 嵌套过多导致的性能问题,对现代浏览器基本没影响吧?对 mobile 浏览器是不是影响更明显?
@poshboytl 昨天刚瞄到一篇文章,也是讲 freelancer 的,大概看了看觉得挺好。晚上有空了配合你写的中文版一起细读!Freelancer personality types: Good, cheap, or quick. Pick two.
@tyaccp_guojian 你直接写 view 当然可以用……只是通过 render
需要通过 Ember 的约定去找 view,没符合约定你就拿它没办法。
不大了解你们的情况,每个项目都有所不同。不过建议你去看 Em.TEMPLATES
里面的东西,了解下 handlebars 怎么执行的。ember-rails 只是帮你在服务器端把 template 编译成了一个个函数。然后把目录名称对应 template 名称而已。template 名称才是 Ember 按约定找到 view 的根本,而不是你的目录结构。
@mjf429 嗯,我加你了,有空交流下技术吧,国内搞 Ember 的本来就不多。
我明白你是 emberapps 下面定义各种 subapps 的模式,包括 template。
比如你是要在 blog 这个 subapp 下测试,假设你的 subapp 叫 Blog,是这么定义的:
# blog.js
window.Blog = Em.Application.create()
那你就把要测试的 route 和 view 都放在 Blog 这个名称下面啊。
@tyaccp_guojian ember-rails 只是帮助你建立目录结构的,你想全部写一个文件里面都可以……写个测试代码还需要定目录结构么?App 只是我定的全局命名空间,用 Em.Application.create()
生成的。你的情况下,就看你用哪个 subapp 了,把 route 和 view 定义在你自己的 subapp 下就行了。
@willmouse @frank_128 嗯,BEM 我后来去 Google 过,这个确实是我无知了。谢谢两位提醒。
@tyaccp_guojian 一个简单的例子:template aaa/bbb/ccc 和 view AaaBbbCccView 会自动关联。
# Route
App.ApplicationRoute = Em.Route.extend
renderTemplate: ->
@_super()
@render 'aaa/bbb/ccc', into: 'application', outlet: 'modal'
# View
App.AaaBbbCccView = Em.View.extend
didInsertElement: ->
alert 'view rendered'
<!-- application.hbs -->
{{outlet modal}}
@tyaccp_guojian 奇怪,我刚才测试了一下,是可以的。你是不是写错了?是 EmberappsPhotoalbumsUploadPictureView
,albums 没有大写。
好奇点开 DevTool 看了一下,我就不想再看了……
<!-- 双横线,怕一个横线看不清楚? -->
<section class="feature feature--first"></section>
<!-- 双横线 & 双下划线,这又是啥规矩? -->
<div class="feature__image feature__image--right"></div>
<!-- 奇怪的命名,内联 css -->
<div class="table" style="height: 509px;"></div>
@tyaccp_guojian 我只是觉得起这么长的模板名字对 Ember 的 COC 而言不方便。比如:
{{render "posts"}}
和
App.SomeRoute = Em.Route.extend
renderTemplate: ->
@render 'posts'
这两处的 render 应该都是传的 template 名称,然后 Ember 会根据约定去找对应的 view。这两种情况下你都没有办法去修改使用哪个 view。要定义 view 并且关联 template 就只能照着约定来。
这也是为什么你的问题里使用 UploadPictureView 没效果的原因,Ember 并不认为它跟 emberapps/photoalbums/upload_picture
有联系,它只会去找 EmberappsPhotoAlbumsUploadPictureView。
@tyaccp_guojian 按照 Ember 的约定,emberapps/photoalbums/upload_picture
对应的 View 应该是 EmberappsPhotoalbumnsUploadPicture。
不过这样做名字实在太长了。我也不确定 renderTemplate 第一个参数是 template 名称还是 view 名称,你可以试试,如果是 template 名称就没办法了,但如果是 view 名称的话,可以考虑这样:
# view
App.UploadPicture = Em.View.extend
templateName: 'emberapps/photoalbums/upload_picture'
# route
App.PhotoAlbumsRoute = Em.Route.extend
renderTemplate: ->
Em.Route.showModal 'upload_picture'
另外说两点:
events
是已经废弃的写法,现在改名叫 actions
了。config.handlebars.template_root
,在 ember-rails 生成的 template 名称中把 emberapps 去掉,比如:config.handlebars.template_root = 'emberapps'
然后可以在浏览器里看看 Em.TEMPLATES
里面的 template 是什么名字。
技术上来说,我实际开发中很少碰到需要动态填充 outlet,回忆了一下,类似的 UI 需求,基本是用以下几种方式解决了:
考虑会不会引起 route 变化,即这个点击操作需不需要用 url 表示状态以便刷新。如果需要,可以把按钮换成 link-to,然后用嵌套 route 去做,特殊情况可以用 route 的 renderTemplate 回调手动填充。
不涉及到 route 变化,使用 controller 中的特殊标记(比如 isEditing)配合 template 中的 if/else,控制某一块区域的显示和隐藏。按钮绑定的 action 只修改那个特殊标记。
{{#if isEditing}}
{{render "post-form" post}}
{{! you can also use component instead of render }}
{{/if}}
notification 网上也有一堆例子,你可以 Google notification 或者 flash,这里就不提了。
最后,可以看一下 Ember API 中的 connectOutlet 和 disconnectOutlet,看是不是你需要的。不过就我的感觉,大部分情况用不到偏底层的东西。
额,大胆预测一下:
第二次:因为妹子受不了 callback 套 callback 而分手; 第三次:因为妹子搞不懂 Java 和 JavaScript 的区别而分手; 第四次:因为妹子写 CoffeeScript 不写 JavaScript 而分手; 第五次:……
注定孤独一生……
还是喜欢正经的,想看看欢乐的我就去微博或者跟妹子聊天去了~ 想问一个无关的问题。你们也是用 Ember.js 对么?你们的 model 层是用的已有框架(ED, EM, EPF)? 还是自己封装 Em.Object 开发的?我是自己写的,最近被这个问题折腾得不轻……
@blackanger @imlcl 更多是个人喜好吧。替换它主要是两点原因:
一是 Foundation 4 开始全局使用 em 作为字体单位。实际开发中我觉得 em 字体不好调试,比如很多时候要在 chrome dev tools 里调整字体看效果。你说类似 1.43352 em 的字体调整大点咋整呢?虽然 Foundation 提供了 px 转 em 的函数,但由于 em 的继承特性,导致有时候你自己还是要考虑下嵌套情况下字体的计算。我查过 em 相对 px 唯一说得上绝对优势的就是在 IE 低版本下对页面缩放的支持了。正好我的项目几乎不 care IE……
二是 sass 组织的太晦涩。如果说 Bootstrap 3 的写法只是在 css 基础上扩展,那 Foundation 4 就完全是 mixin 的组合,模块化是个好事,但也造成了代码不易懂。扩展既有样式时尤其如此。当它提供的配置达不到你的需求,mixin 的组合也不能完全满足你时。你能做的就是看懂它的 mixin 然后再去用 css 的覆盖规则去改写了。而我觉得那些 mixin 写的太复杂了。相比起来 Bootstrap 3 也用模块,但不像 Foundation 那么过度,都挺好理解。
其他什么体积大之类的我倒是没觉得有什么问题。
顺便吐吐 Bootstrap 3 的槽,那个命名规则和 html 嵌套结构相比起来确实比较啰嗦。
下个项目考虑用 Semantic UI,已经从 Foundation 4 换 Bootstrap 3 了一次,深感各种折腾。
好久没用 ED 了。对 model 调用 reload 是什么结果?重新调用 GET /api/orders/:id
去更新一遍吗?
不是,是说的 REST API 的自定义 url。
你知道默认的 REST API 有五个 url:
但有时需要超出这些之外的,自定义的 url,比如:
不然默认的五个 url 是不够应对实际使用情况的。
在 Ember Data 里面要实现这个比较麻烦。需要自定义的太多,没有很方便的处理方法。作为 Ember Data 的 json 规范的 JSON API 也完全没有提及超出默认 REST API 的情况应该怎么设计 API。而且在 Github issues 里面我也没搜到相应的讨论和解决方案。所以我才说不知道最终版会是什么样子,不知道会不会支持这种特性。
关于一些 Ember Data 欠缺的东西,可以看看 10 Things You Can Do With EPF (That You Can't Easily Do With Ember Data) 。虽然文章比较老,现在一些东西比如 transaction 已经被 Ember Data 改掉了,但文章还是值得参考。
fork 特性倒是有提及,但也仅仅是提及而已,说不定会等到 Ember Data 1.x 去了。
Ember Data 的 beta 版我只用了很短一段时间,感觉是做好了的功能都考虑的比较完善,但一旦你需要它没有的功能,就比较难扩展。所以用到最后估计会作为 contributor 去一起加功能和修 bug。就像 EPF 作者说的一句话:If you use Ember Data, you will be a contributor.
没有 EPF 那样的 fork 特性,没有 custom action 支持,现在还不好说最终版是什么样子。
我的比较原始,因为觉得单屏幕怎么也没办法同时放多个 app(iMac 除外)。Chrome, Terminal, Vim 三个基本就是所有选项了。Vim 开全屏,用手势来回切换,Chrome 在主屏幕放到最大,Terminal 也在主屏幕,有需要用 tab 切换。
现在前端 MVC 没发展到很成熟的地步,各有各的坑,没有很完美的解决方案。所以只能挑个最合适自己的。自己选几个,写同样一个应用试试就知道了。
个人偏向 Ember.js,一个更类似于 Rails 那样提供整套解决方案的框架。从底层的各种工具函数(string format, array 迭代器等)到稍高的 object 封装和 mixin,reopen class & object(尼玛这就是 Ruby 的翻版),computed property,到整体框架构建无所不包,除了 UI 层不用操心再单独加其他的工具集了。
但建议别用 Ember Data …… beta 版不够用,master 又改变太频繁,几个作者经常为了思考更通用的解决方案而把以前的东西否定掉。没稳定之前建议别用。
相比起来 EPF 是个不错的选择。
想了解 Angular 和 Ember 对比的,这篇文章还不错 http://eviltrout.com/2013/06/15/ember-vs-angular.html ,记得也看看评论,会有不少收获。
你如果用 Rails 的 asset pipeline 的话,那就跟 Rails 里的用法一样啊。我没这样搞过,只能说说我想到的,不见得对:
CSS 和 SASS 里的图片链接不用管,使用 image-url 这种 helper 就行。 handlebars 模板里面的估计就只能用 some_template.hbs.erb 来做了。
研究一下 Rails Guide 就明白了 http://guides.rubyonrails.org/asset_pipeline.html#css-and-sass
照 Ember 官网弄的网站?header 的背景挂了,图片找不到……看报错页面样式貌似是 Rails 4 的?估计是 precompile assets 的问题。
谢谢!vim-easy-align 真是五星级插件。我觉得最厉害的是常用代码缩进方式很智能。
比如 js 或者 ruby 代码中的 :
:
{
a: 1,
bb: 2,
ccc: 3,
}
可以缩进成这样(它知道把 :
贴近 key):
{
a: 1,
bb: 2,
ccc: 3,
}
而在对于这种:
{
a => 1,
bb => 2,
ccc => 3,
}
它知道把 =>
放在中间并且两边留空格,而且 delimiter 只用写 =
就行了:
{
a => 1,
bb => 2,
ccc => 3,
}
其实大多数的情况下需要的 align 都很简单,只要用起来不复杂就行,这个插件做的挺人性化的。
粗暴的 table 布局……
一直在跟,本来觉得 1.0 相对 rc-8 不会有什么大更新的,结果发现更新超出想象,文档的完善,AMD modules,Ember inspector 进 Chrome App Store,Ember Data 也有更多的自定义了,可以说真正到了可以拿进项目用的程度(不过就算还有缺陷也还有 EPF 可用)。
唯一残念的是 Ember Data 果然还是没 1.0,不过好歹终于 beta 了。照 Core team 的节奏估计 1.0 正式版出了也会有点惊喜。
好文!第一次知道 Cells 还是通过 LZ 以前的介绍文章知道的。Rails 一个页面一个 Controller 的方式,对于越来越复杂的页面来说确实不够用了。Cells 这种把页面分块设计 Controller/View 的方式更为科学。其实前端 MVC 现在大都也使用的这种方式。