How do I create a list page?

Source: Internet
Author: User

How do I create a list page?

Recently, it is rare that the company's business has been slightly mitigated. We finally have time to calm down and summarize the technology. Our goal is to extract the essence of the previous project:

  • Solve the development efficiency problem of the background management system, encapsulate common functions, and separate technical content;
  • Unify repetitive development work with technical specifications to avoid separate research;
  • Using best practices, referring to excellent projects, and developing the best method is at least the most suitable for the current team.

Here I will summarize my practices on the data list page first, and then add the practices of other modules. I will first look at the requirements on the list page:

  • Search conditions support dynamic condition query, and the backend does not need to intervene in the assembly of related conditions; that is, the following code cannot appear (Note: This method is only for single-table queries, this scheme may not be the best if it is a very complex multi-Table Association)
       if(!StringUtils.isEmpty(employeeEnityRequest.getEmployeeName())){            criteria.andEmployeeNameEqualTo(employeeEnityRequest.getEmployeeName());        }        if(!StringUtils.isEmpty(employeeEnityRequest.getEmployeeStatus())){            criteria.andEmployeeStatusEqualTo(Integer.valueOf(employeeEnityRequest.getEmployeeStatus()));        }

 

  • The query is asynchronous. When you click the next page, the experience of refreshing the entire page is not good.

The above two requirements are very common and there are many implementation methods. I will share my practices (my environment is eclipse, tomcat, maven, spring mvc, mybatise, mysql ):

For dynamic queries, we use agreed rules. For example, in View, we can write

<input type="text" name="WHERE.storeName.LIKE"    class="form-control" style="width: 180px;" " />

 

It means to query the email field, and the operator is =. The WHERE clause is fixed. It is used for identification when parsing collection conditions in the background. The field names are in the middle, followed by operators, such as common database query operators such as EQ and LIKE. In this way, we can add any modification conditions on the front end, and the background logic does not need to have a task change. For detailed collection process, please refer to the introduction below.

For Asynchronous queries, I used angularjs-related technologies. At that time, I encountered a problem: angularjs usually designated a well-written model during query and passed it to the background, however, the above dynamic query condition is changed (the Field name is not fixed, the number of fields is not fixed, and the operation type is not fixed), so there is no way to define such a model. The first instinct is to pass the entire form to the background, and the background solves specific conditions based on the form value. The second problem arises. Since the form is passed to the background, so what parameters should be used in the background to receive this form? I thought of HttpServletRequest at the time, but after testing, this parameter was never taken. The code at that time was as follows:
Java

    @RequestMapping(value = "/getStoreByPage", method = RequestMethod.POST)    @ResponseBody    public PageInfo<BcStore> getStoreByPage(HttpServletRequest request,int pageNum, int pageSize) {

Js

$.ajax({    type : "POST",    url : url,    dataType : 'json',    data:$("#searchForm").serialize(),    async : false,    success : function(data) {        $scopeLocal.pageResponse = data;        $scopeLocal.content=data.list;    }});


Later, I discussed with my colleagues that the contentType of ajax needs to be set to application/x-www-form-urlencoded, but an error is reported directly after the setting. The request cannot reach the server, indicating that the parameter type is incorrect, the parameter HttpServletRequest in the controller Method in the background is successfully deleted. However, if this parameter is deleted, Where can the form value be taken? Fortunately, the backend can also get the current request, and RequestContextHolder can help us, so the following code is ready. Through this help class, we can parse the conditions in the request according to our rules, the format of the condition object mainly depends on the usage of the data access end. No code is posted here. We mainly use the general mapper solution, which can be searched online. At this point, the problem is solved, and the data can be found smoothly.

private static String DEFAULT_PRE_WHERE = "WHERE.";private String preWhere = DEFAULT_PRE_WHERE;List<String> searchFilterStrings = Lists.newArrayList();        Map<String, String[]> map = request.getParameterMap();        for (Map.Entry<String, String[]> entry : map.entrySet()) {            String strKey = entry.getKey();            for (String value : entry.getValue()) {                if (!Strings.isNullOrEmpty(value)                        && !"none".equals(value)                        && strKey.startsWith(preWhere)) {                    String filedAndOp = strKey.substring(preWhere.length());                    searchFilterStrings.add(String.format("%s.%s", filedAndOp, value));                }            }        }


I didn't use controls such as jquery datatable to display list data. I felt that I needed to write JS Code and it looked complicated. The ng-repeat of angularjs was very intuitive and easy to control details.

<Table id = "datatable1" cellpadding = "0" cellspacing = "0" border = "0" class = "datatable table-striped table-bordered table-hover"> <thead> <tr> <th> store No. </th> <th> name </th> <th> type </th> <th> store manager </th> <th> phone number </th> <th> email address </th> <th> Status </th> <th> creation time </th> <th> operation </th>/ tr> </thead> <tbody> <tr ng-repeat = "store in content"> <td >{{ store. storeCode }}</td> <td >{{ store. storeName }}</td> <div ng-show = "store. storeType = '1' "> <span class =" label-success "> self-owned stores </span> </div> <div ng-show =" store. storeType = '0' "> <span class =" label-danger "> franchise stores </span> </div> </td>


Paging control we use angularjs and boostrap plug-in to complete, need to reference ui-bootstrap-tpls.min.js and boostrap-ui-related code to do:

<Pagination class = "pagination-sm" ng-model = "pageRequest. pageNum "total-items =" pageResponse. total "max-size =" 4 "ng-change =" pageRequest. getResponse () "items-per-page =" pageRequest. pageSize "rotate =" false "previous-text =" previous "next-text =" next "> </pagination>


Js Code. In order to make the front-end call method, we try to encapsulate it so that the query logic only needs to write the least code: inject a $ listService, then you can pass a request address to it. Of course, there are some fixed writing methods, such as the attributes of a request object, which must be configured in the front and back, and cannot be written at will.

var mainApp = angular.module('storeManageApp',['ui.bootstrap']);      $.initListService(mainApp);     mainApp.controller('storeManageCtrl', function ($scope, $http,$listService) {                var listUrl="<c:url value="/store/getAllByPage"/>";                $listService.init($scope,listUrl);                $listService.get();                            });

Angularjs injection is good. Our encapsulated js is also completed based on the service mode provided by angularjs: As this service requires angular objects, a jquery Extension function is created, easy to call, the code in the function is relatively simple, the General service writing method, here pointed out that ajax submitted parameters in the background I did not use the data parameter, but directly spliced on the url, the contentType should be added to the data.

jQuery.extend({    initListService: function(mainApp) {        mainApp.service('$listService', function(){                  var $scopeLocal={};              this.init = function($scope,listUrl) {                   $scopeLocal=$scope;                  $scopeLocal.pageRequest = {                        "pageNum": 1, "pageSize": "5"                     };                  $scopeLocal.pageRequest.getResponse = function () {                     var requestData = $("#searchForm").serialize();                     var url = listUrl+"?"+requestData+"&pageNum="+$scopeLocal.pageRequest.pageNum;                     $.ajax({                         type : "POST",                         url : url,                         dataType : 'json',                         async : false,                         success : function(data) {                             $scopeLocal.pageResponse = data;                             $scopeLocal.content=data.list;                         }                     });                                  }                 this.get = function() {                      $scopeLocal.pageRequest.getResponse();                 };                                         }        });    }});

 

On the last list page:

 

The function looks good, but there are still some imperfections. For example, we should provide several data loading events to facilitate some special processing operations before and after data loading. However, in a good start, the efficiency of subsequent team members can be improved by referring to this template. Of course, the efficiency improvement is not only described in this article, but also the integration of permission filtering, encapsulation of various controls and other functions.

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.