对于前端 MVC 来说, DOM API 是否是过度封装了?


没从 C++/Java 学起, 对 MVC 和面向对象的理解还是后来慢慢积累起来的
相对我觉得脚本语言各种范式各种灵活, 只是缺少面向对象组织代码的整齐呆板
而且从前使用 DOM API 时候就觉得 DOM 就像一种数据类型,
JS 操作数据同时, 也在更改界面. 通过直接访问界面, 也能读取数据, 很强大对吧

但我接触 Backbone 一段时间, 困惑也觉得越来越多
而从前灵活解决前端问题的思路, 随着 MVC 提出的分离有了各种阻碍, 或者不方便直接 JS DOM 操作吧
MVC 在 Backbone 里是 Model 和 View-Controller 两者分离, 另加上 Collection.
每次 Model(Collection) 发生改变, View 重新渲染一次, 然后搞定
或者 DOM 上的事件从 Controller 传到 Model 里进行一次改变, View 跟着改变好
这样其实 jQuery 丰富的 DOM 操作就显得无所用处

如果在 Backbone 的应用里加上大量的 DOM 操作, View 刷新时又变得尴尬
为了性能, JS 在进行 DOM 操作时会讲操作全在 HTML 字符串里存储好, 一次写入
可在 Backbone 里, 如果小的 item 也是 Model, 那么 render 也是分开了自己做的
我理解, 这样两者就不能够很好地兼容, 至少有一个方面要打折扣了

另一个功能是实时保存和更新, 纯的 DOM 操作, JS 监听 DOM, 在背后保存数据很简单
可在 MVC 里 Model 被监听, 每次更新操作就会导致界面被重新绘制, 也显得很怪

backbone dom mvc JavaScript

八云移动中心 10 years, 12 months ago

最早的时候,业务很简单,我们写样的代码。

$.ajax({
    url: 'http://ooxx.cn/getUser'
    success: function(user){
      //进行DOM操作
      $('#name').val(user.name);
      $('#email').val(user.email);
    }
  })

后来,user 的字段越来越多。

$.ajax({
    url: 'http://ooxx.cn/getUser'
    success: function(user){
      //进行DOM操作
      $('#name').val(user.name);
      $('#email').val(user.email);
      $('#address').val(user.address);
      $('#phone').val(user.phone);
      $('#blog').val(user.blog);
      //可能还有更多的字段,并且DOM操作不一定这么简单只是值的修改
      //可能还要负责整个视图是否出现:比如 isVIP 为 false 时,出现付费引导等。
    }
  })

于是我们考虑将对象与模版进行绑定,进一步抽离

$.ajax({
    url: 'http://ooxx.cn/getUser'
    success: function(user){
      rener(user);
    }
  })

  var render = function(obj){
      //进行DOM操作
      $('#name').val(user.name);
      $('#email').val(user.email);
      $('#address').val(user.address);
      $('#phone').val(user.phone);
      $('#blog').val(user.blog);
  }

只是简单的代码封装,整个结构就清晰很多。但紧接着,我们开始使用 websocket 来做界面的即时更新,于是代码再次修改。

这是一个用户列表

socket = new WebSocket("ws://192.168.1.71:7070");
  socket.onmessage = function(data) {
      var obj = JSON.parse(data)
      if(obj.action === "update"){
          render(userList);
      }
  }

  var render = function(obj){
      //进行DOM操作
      $('#name').val(user.name);
      $('#email').val(user.email);
      $('#address').val(user.address);
      $('#phone').val(user.phone);
      $('#blog').val(user.blog);
  }

很棒,接着我们想像到这个 user 将会有非常多的 function,如果到处是 $("") 这样的方式进行DOM操作,如果有一天,HTML 上的 id/class 要稍变一下,那改起来就痛苦了。
把用户这个做成 Model,加上 render(), showPhone(), sendEmail() 这样各种的方法。将大大增加代码的组织能力。

-------------------------

其实上面写了这么多,只是想说明,需求在不断增加的时候,项目不断变大的时候,原有的代码组织无法满足需要,需要站在各高的层次,将项目中常用的方法进行抽离封装。于是,便有了框架。

backbone 做得事很专注,充分发挥MVC的组织分层能力,继续把DOM交给 jQuery 去做。

而更新的前端MVC框架,如:angularjs, emberjs 等,将 model 与 template(HTML) 进行绑定,直接帮助你渲染,让我们不用再关心渲染、DOM处理,而是把注意力集中在业务及交互处理上。

既然是框架,解决的必然是复杂的、复杂的事情。如果只是简单的几个DOM处理,用框架肯定是太重太浪费了。

红蝶Saika answered 10 years, 12 months ago

Your Answer