[wicket] 怀着学习的心态探讨wicket的不足,请指教
vulcan
2010-06-18
刚刚看了一下wicket, 有点疑惑,请各位先研究的同学指教:
起因:Seam 2.2.0 支持wicket作为表示层框架,所以看了看seam中的使用wicket做的booking例子,不过第一印象没有想象中的美好,总的感觉是像DotNet 2003的情况,在页面中用标签(wicket是用纯的xhtml加wicket:id的情况)定义一些控件,然后在后台代码中还要把所有的控件全部用编程的方法定义一遍,这就是我当初恶心DotNet 1.1,VS 2003的原因,而到了Dot Net 2.0, VS 2005,有了Partial Class的概念,那么重复性的工作不用做了,并且DotNet 3.5, VS 2008,方便程度又有了进一步的发展。不过在Java的世界中,基于组件和事件编程的框架远没有DotNet中来得好,不论是基础框架还是IDE支持。 现在不是流行Ajax吗,如果我全部要用id来指示每个可以绑定数据的控件,还要在后台代码里面声明每个控件,我为什么不选择使用JSON传递一个DTO对象过来,然后用jQuery这种可以灵活操作DOM的JavaScript框架,绑定对象到表格或者控件呢?再说seam中默认的使用JSF作为标识层的情况,感觉却还好,之所以可以忍受JSF的标签,是因为标签为我们封装了太多的功能,比如数据校验,数据转换,状态维护等等一系列功能,就说这个DataTable数据绑定,JSF中也比wicket中来得直观很多,页面中一个id,代码中一个id,而且这种IDE根本不好支持自动补全,而不像JSF中使用EL,IDE可以提示;既然这样,还不如使用jQuery绑定数据到页面组件中。比如我可以用下面的JS代码绑定JSON数据到HTML Table /** * bind data to a table * @Author: Yi Can alva.yi@gmail.com * TODO add table sort and pagination * var data = [{id:1, foo: 'foovalue', bar: 'barvalue'}, * {id:2, foo: 'foovalue2', bar: 'barvalue2'}]; * <table id="foobar"> * <tr> * <td>ID</td> * <td>FOO</td> * <td>BAR</td> * </tr> * <tr> * <td id="id"></td> * <td id="foo"></td> * <td id="bar"></td> * </tr> * </table> * $.bindTable('#foobar', data); * @selector - the jquery selector to get the table * @data - the paged data * @rowCallback - call the callback function before insert a row * arguments: currentRow - current row to be added to the table * row_index - the current row idx, start from zero * data - the given data list * @cellCallback - call the callback function before bind value to a cell * arguments: currentCell - the current cell to be filled * key - the key of current cell * row_data - data for the current row to be added to the table */ jQuery.extend({ /** * bind data to the table or add data to the table * if you want to rebind the data, you must use clearTable first */ bindTable: function(selector, data, rowCallback, cellCallback) { if (! $(selector).is('table')) { alert('the selector must match a table element.'); return; } //clone a row of tbody var modelRow = null; var container = $(selector); //get the first 'tr' var ridx = 0; //the first row //find the max tr number var rowCount = $('tr', selector).size(); while(ridx < rowCount) { modelRow = $('tr:eq('+ridx+')', selector); if ($('td[id]', modelRow).size() > 0) { break; } else { ridx++; } } // the model row was found if ($('td[id]', modelRow).size() == 0) { alert("no model row was found, a row with id for cells is required."); return; //no model row } //iterator over the data if ($.isArray(data) && data.length > 0) { modelRow.show().remove(); //remove the model row from the container for (var i = 0; i < data.length; i++) { var newRow = modelRow.clone(); //callback if (rowCallback && $.isFunction(rowCallback)) { rowCallback(newRow, i, data);//give the data to be bound } $('td[id]', newRow).each(function(){ var key = $(this).attr('id'); if (cellCallback && $.isFunction(cellCallback)) { cellCallback($(this), key, data[i]);//give the data row to be bound } //support automatic date format by css class var value = data[i][key]; if ($(this).hasClass('date') && value) { //format the json date to the yyyy-MM-dd if (typeof(value) == 'string') { var pos = value.indexOf('T'); if (pos != -1) { value = value.substring(0, pos); } } if (typeof(value) == 'number') { var t = new Date(value); var y = t.getFullYear(); var m = t.getMonth() + 1; var d = t.getDate(); //correct the digits if (m < 10) m = "0" + m; if (d < 10) d = "0" + d; value = y + "-" + m + "-" + d; } } $(this).text(value); }); if (! newRow.attr('id')) { newRow.attr('id', 'r_'+i); //add a default row id } //insert the new row to the container container.append(newRow); } } //TODO cope with the give Page<T> DTO }, /** * get the a dict of a row from the table */ getRowData: function(selector, idx) { if (! $(selector).is('table')) { alert('the selector must match a table element.'); return null; } //find the target row var targetRow = $('tr:eq('+idx+')', selector); if (targetRow.size() == 0) { return {}; //not found } var data = {}; $('td[id]', targetRow).each(function(){ var key = $(this).attr('id'); data[key] = $.trim($(this).text()); }); return data; }, /** * clear the data table and only leave the model row */ resetTable: function(selector) { //get the first 'tr' var ridx = 0; //the first row var modelRow = null; //find the max tr number var rowCount = $('tr', selector).size(); while(ridx < rowCount) { modelRow = $('tr:eq('+ridx+')', selector); if ($('td[id]', modelRow).size() > 0) { break; } else { ridx++; } } // the model row was found if (modelRow != null && $('td[id]', modelRow).size() > 0) { $('tr:gt('+ridx+')', selector).remove(); // clear the model row $('td[id]', modelRow).each(function(){ $(this).text(''); //empty the cell }); modelRow.hide(); //hide the model row } } }); |
|
parkerwy
2010-06-27
使用JSF或wicket正是为了不用写或少写这样的javascript。
|
|
key232323
2012-03-20
我走了和楼主一样的路子——不过我整理的工具库粒度更细点——比较适合我们公司的业务场景需求。
|
|
greateWei
2012-04-07
parkerwy 写道 使用JSF或wicket正是为了不用写或少写这样的javascript。
一语中的, |
|
lxw_first
2012-04-26
wicket实现弹出层,除过ModalWindow,还有无其他实现方式?ModalWindow为遮罩层,弹出后原页面就不能操作;现在要原页面能继续操作,如何实现?主要是想实现模糊查询过滤后的自动完成功能,并能实现多选功能。
|
|
avyi
2013-01-05
wicket直接架起了UI和Business Tier的关系,不需要考虑浏览器中JS和后端之间的通信,wicket全部帮你封装处理掉了。如果用你的方式,除非整个应用的UI全部放到浏览器中用HTML5/JQuery开发,否则就会多引入一层Browser中程序和后端web上程序通信的过程,需要考虑前后端的数据通信格式、timeout、重复、前进后退等一系列问题,所以总的工作量和考虑的地方要多。但wicket要求程序员的OO思想一定掌握到位,要不会感觉用起来不爽,但一旦掌握wicket,就很少有人再离开wicket。也许这就是为什么在国外wicket比较流行的原因吧。
|
|
avyi
2013-01-05
博主与NET的比较的确是个问题。wicket要是有个图形化界面编辑工具就可以进一步提高效率,但国外的wicket那帮人一定要保持wicket的中立性,不肯绑定在特定工具上。另外一个原因是尽管这样看上去啰嗦一些,但是在一个大项目中,coding那几句代码废不了多少时间,因为套路是固定的,都不用动脑筋闭着眼new出来add进去就成。MS$在这点上确实要好,但是它是以语法的增加和与特定IDE的集成为代价的。保持最大限度的通用性和底层支持平台的功能集合最小是国外开源社区的典型做法,java不肯盲目增加新的语法特征也是基于这种考虑,要不然他怎么能够容易它的跨平台特性,而且能够跨越从嵌入式到企业级这么宽的应用范围。java世界和net世界是两种理念,所以才会造出这么多差异。
|