Eisen's Blog

© 2023. All rights reserved.

最近工作的总结

July 02, 2013

jquery工作总结

每一段经历都是有意义的。一方面是在这个过程中的感受,另一方面是经历了这个之后的收获。最近又有些疏于码字了。赶紧补一补。记录一些最近工作的一些感想。

用类 dsl 去管理表单的展现

首先当然是讲一讲技术方面的。最近接触了一些相对来说比较复杂的表单:对,就是那种

对于一个下拉选框的每一个选项
  if option == 1 then
    表单 1
  else if option == 2 then
    表单 2
  else if
  ...
  end
end

其中,表单 1 到 表单 n 都不不太一样。然后,还要杂揉着表单验证以及自定义的表单组件。

就具体工作来讲,对每次 select change 事件做出不同的响应是不可避免的。但是,这样的代码往往很难看,并且显得臃肿而不灵活。但是,对于这种业务逻辑与代码要紧密结合的事情,又能有更好的办法么。

首先,我个人感觉,这种工作不可避免。它涉及业务逻辑。而业务逻辑就是人定义的。人的干涉不可避免。那么,就最好去简化这种工作。让人只做最关键的东西,尽量做抽象。对于目前这种工作,人需要提供的就是规则:什么时候应该显示什么表单,什么时候不应该显示什么表单。

然后,我找到了一个比较理想的 lib jquery-interdependencies。这个东西所提供的功能恰好就是我所需要的。它就是一个类似于 dsl 的东西:我告诉它当一个东西的值等于什么的时候,应该做什么。下面是其 github 页面上所提供的一个例子。

// Start creating a new ruleset
var ruleset = $.deps.createRuleset();

// 这里就是指定一条条的规则了。当一个 xx 的值 是 xx 然后就 xxx
var dietRule = ruleset.createRule("#diet", "==", "special");
dietRule.include("#special-diet");

// Make these fields visible when user checks hotel accomodation
var hotelRule = ruleset.createRule("#accomodation", "==", true);
hotelRule.include("#adults");
hotelRule.include("#children");

// Make the ruleset effective on the whole page
ruleset.install({log: true});

写这种简单的规则让我觉得比自己建立事件并配合 switch case 要好很多。我很高兴有人已经提供了这样的 lib。

但是,这里还有一个问题有待处理。如果我们使用 html 里默认的表单提交方式的话。即便是被隐藏的表单,它们的值也会被提交。这并不是我想要的。应该怎么办呢?html 有一个这样的规则,如果 form 中的一个 input 是 disabled 那么它的结果是不会被提交的。那么,我们需要在 interdependencies 帮助我们隐藏表单的同时将要隐藏的字段做 disable 处理,而在显示的时候则将其 disable 去掉即可。谢天谢地,jquery-interdependencies 给我们提供了这种 callback 的机制。

cfg =
  hide: (control) ->
    control.find('input, textarea, select').attr('disabled', true)
    control.hide()
  show: (control) ->
    control.find('input, textarea, select').attr('disabled', false)
    control.show()

这样的话,每次提交表单,其内容就是我们所需要的了。

用前端模版去渲染界面

其实之前的项目就有这么做了。但这次有多学了一招。

之前使用 handlebars 都是和 backbone 做配合。而这次呢,是要简化复杂的界面呈现。这里用到了一个 gem handlebars_assets。它可以帮助预编译前端的 handlebars 模版。而不必每次使用的时候都去使用 Handlebars compile 去重新编译。并且,利用 assets pipeline 可以将每个模版写成独立的文件。

   templates/
      contacts/
        new.hbs
        edit.hbs
        show.hbs

这样的支持让我不用在代码的组织上费什么脑筋了。

coffee 对象的封装

项目中是用 coffee 而不是用 javascript。在考虑将一坨一坨的代码按照 js 的方式

var abc = (function() {
  bla bla…

  return {
    bla bla...
  };
})();

进行的时候发现 coffee 中对应的语法显得非常古怪。我甚至想要放弃 coffee 了。但是,转念一想,coffee 简化了 js 中类的定义和使用。coffee#class 有比较详尽的说明。

用这个做封装其实刚刚好。

class DateRangeGenerator
  day = 1000 * 86400
  week = day * 7
  year = day * 365

  date_format = (date) ->
    date = new Date(+date)
    "#{date.getFullYear()}-#{date.getMonth() + 1}-#{date.getDate()}"

  generate_range = (time, num) ->
    (date_format(new Date() - time * period) for period in [0...num]).reverse()

  day_range: (num) ->
    generate_range(day, num)

  week_range: (num) ->
    generate_range(week, num)

  year_range: (num) ->
    generate_range(year, num)

上面是我建立的一个类的示例。把代码这里整理之后其实比 jquery 那种胡乱点点的函数用来用去要强很多。


下面就是吐槽了。

其实很多时候,当我们接受一个半途的项目的时候,都会有强烈吐槽的欲望。可能代码的风格不和你的意,可能项目的理念和你不相投。可能代码就是一片混乱,难以下手。但是,静下来看看,总还是可以着手去工作的。与其以一个极端对立的态度给自己打退堂鼓,不如说静下心来想办法如何应对。

当然,上一段说的有点扯淡。关键是应该要怎么想,要怎么做吧。

别人的代码搓是别人的代码。不能说别人的不好,我的也无所谓了。最起码的,别人的东西我不帮忙收拾就罢了,但是从我的开始,我会让它尽量好起来。起码要对自己的代码负责任,然后再能者多劳吧。

给别人做项目的时候要有一定的主动权。其实很多客户给你提要求的时候并不一定是深思熟虑了。他们可能也是一时随口一说。但是如果自己不好好权衡和争取的话,可能会拖慢了进度又做不出客户想要的结果。而且,有的时候真正的客户也不是给你钱的人,那么就更要多沟通,灵活点。