Hybird app 不见得开发成本低。只是更适合 web 开发者罢了。而 web 开发者远比 iOS / Android 开发者多,所以你懂的……但这不代表随便找个懂点 jQuery 的就能干活。举个栗子,做一套 UI 能够适应 iPhone / iPad 和各种主流分辨率的 Android 机型就不是件容易的事情。
而且浏览器有浏览器的坑,不下于以前前端工程师考虑桌面浏览器兼容的情况。一些对 native app 开发者完全不是问题的东西到 hybird app 中就需要各种 hack……
创业做效率工具必须赞一个。
我在想,如果这玩意开放 API 的话,也许直接建一个 example 然后把它当数据库用~
@rainsz +1 走在路上,蹒跚探路。
武汉也属于重度污染城市啊,命不久矣~
@QueXuQ 我对 ED 用的也不是很多,但 ED 这种客户端 model 层都有种客户端缓存的概念,deleteRecord 是删除客户端 record 可能只是改变状态,让你在客户端能过滤掉这个数据,save 把改变同步到服务端去。
这个没所谓哪种 pattern 更好,看你的实际需要而定。
@coderek 这就是各个框架的设计哲学了。Ember 就是 strong opnionated 的。作者认为对 web 开发而言,有很多架构问题是大部分 web app 都会遇到的,而“常见的问题需要通用的解决方案”,避免开发者在什么才是最好的构架方式上纠结从而浪费时间。marionette 仅仅提供的是点,而不是面,Angular 则只提供地基。但这没什么不好,如果开发者很清楚自己在做什么,有自己的一套架构,那么选择灵活性高的框架是更适合的选择。
最简单的做法:
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
@QueXuQ 嗯,建议自己写的时候不要做 camelcase 和 underscore 格式的转换,因为这意味着你要处理两种逻辑:
往往一个简单的赋值就要变成写循环去转换 key,多了一堆代码,而且处理不慎会比较容易出错。
所以我对 model 字段名都是用的 underscore 格式。不和谐就不和谐吧。
@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 更轻量,碰到问题更容易扩展,其实也没那么灵活。
@fresh_fish 原来是 Bootstrap 2 的 span class,不然提交一个 PR 到 Bootstrap,一样可以光宗耀祖。
@HungYuHei 原来如此~ 我还在想你们前端那么坚定的 Angular 支持者怎么居然转换立场了。
@HungYuHei 你们居然换 Ember 了……原先的 Angular 不用了?
The new GUI architecture,Vim 终于有望做成 Sublime 那种现代 GUI 了
支持一下武汉同胞。
各种夹鸟……又浪费时间了~
@kenshin54 哈哈,其实不是说更新频率。我应该算是比较叼吧,昨天 app 提示我开启定位服务,好奇之下点了个“帮助”,发现里面截图还是 iOS 6 的,所以误以为没怎么更新。
点评的 app 应该更新一下了
@cassiuschen 确实 Ruby Conf 那个很有范啊。
@Rei 这也是无奈之举。但现实就是如此。制定标准是个耗时又头痛的事情,Google 貌似没出什么标准,设备生产商更不会去干这事。最终结果就是交给开发者去头痛了。
要做到这一点,除非厂商走软硬件结合的路线,为自家的平台打造好的生态环境,而且最好限制不同屏幕尺寸的数量。Apple 就是这么干的。retina 和非 retina 在 css 中的分辨率都是一样的,使用同一套代码完全没有任何障碍。
短暂用过一个月 Foundation 4,后来换到 Bootstrap 3 了。主要是因为源码太复杂和 em 继承性比较折腾。不过如果再让我选择一次,也许会使用 Foundation 5。
@Saito @Rei rem 最大的作用是在 mobile 浏览器上。因为不同的设备有不同的分辨率,但不管是高 dpi 屏幕还是低 dpi 屏幕,UI 比例都维持不变。
这种情况下在 body 中使用 px 设置基础字体大小,下层标签使用 rem 去设置字体,宽高等。然后对不同分辨率的屏幕使用 media query 改变 body 里的 font-size。基本可以做到一套 css 适配 iPhone 和 Android 的主流机型。
@ruohanc 笔误……还好你注意到了,谢谢指正!
@lgn21st 你也是用 logdown?握手~
本来也下了这个插件,但我的 API 比较奇葩,还是用 cookie 的,所以……
@ask_acct 歪个楼,麦咖啡攒够四辈可以免一杯。如果四次都喝美式咖啡,最后来杯拿铁,平均一杯就才 12,还是挺划算的……
@allenlsy 查了一下 OWL,新加坡猫头鹰三合一咖啡。含有植脂末。这玩意是不是对身体不健康啊?
不考虑旧式浏览器的话,纯 css 的方法可以这样做,最大限度的撑大背景图并居中显示。
.img-responsive {
background-size: cover;
background-position: 50% 50%;
}
@billy 突然想起来了,可能单独使用 Handlebars 这样写没问题,但在 Ember 里就不行了,因为 Ember 为了 data binding 会生成 script 标签包裹内容。slide 里面那一堆带 script 的例子就是……