首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 綜合教學

AngularJS 列表頁最佳實踐:Directive + Service 實現動態查詢、排序、分頁與 Model 實時更新

     編輯:Java 綜合教學

業務場景與技術棧

後台管理系統列表頁通用需求:動態條件搜索、列頭排序、分頁導航、單行操作後 Model 實時更新(無需刷新/二次請求)。技術棧:AngularJS (MVVM) + Spring MVC + HTML Table(輕量、原生支持雙向綁定)。

核心架構:Service 封裝通用邏輯

angular.module('app.service', ['app.constant'])
.service('$listService', function () {
  var defaultOptions = {
    pageSize: 10,
    searchFormId: 'searchForm',
    beforeSend: function () {},
    callback: function ($scope, data) {},
    error: function () {}
  };
  this.init = function ($scope, option) {
    var opts = $.extend({}, defaultOptions, option);
    $scope.pageSizeList = [{text:'10',value:'10'},{text:'20',value:'20'}];
    $scope.pageRequest = {
      pageNum: 1,
      pageSize: opts.pageSize,
      orderBy: '',
      getResponse: function (orderBy) {
        var requestData = $('#' + opts.searchFormId).serialize();
        var url = opts.listUrl + '?' + requestData +
                  '&pageNum=' + this.pageNum +
                  '&pageSize=' + this.pageSize;
        if (this.orderBy) url += '&orderBy=' + this.orderBy;
        $.ajax({
          type: 'POST', url: url, dataType: 'json', async: false,
          beforeSend: opts.beforeSend, error: opts.error,
          success: function (data) {
            $scope.pageResponse = data;
            $scope.content = data.list;
            opts.callback($scope, data);
          }
        });
      }
    };
  };
  this.get = function () { $scope.pageRequest.getResponse(); };
});

Controller 使用示例

mainApp.controller('manageCtrl', function ($scope, $listService) {
  $listService.init($scope, { listUrl: '<c:url value="/theme/getAllByPage"/>' });
  $listService.get();
});

Directive 實現列頭排序

angular.module('app.directives', [])
.directive('sortName', function () {
  return {
    restrict: 'A',
    link: function (scope, element, attrs) {
      var sortName = attrs.sortName;
      var sortType = attrs.sortType || 'asc';
      element.addClass('sorting').attr('sort-type', sortType);
      element.on('click', function () {
        var $this = $(this);
        var type = $this.attr('sort-type');
        scope.pageRequest.orderBy = sortName + ' ' + type;
        scope.pageRequest.getResponse();
        $this.removeClass('sorting sorting_asc sorting_desc')
             .addClass(type === 'asc' ? 'sorting_asc' : 'sorting_desc')
             .attr('sort-type', type === 'asc' ? 'desc' : 'asc');
        $this.siblings('[sort-name]').removeClass('sorting_asc sorting_desc').addClass('sorting');
        scope.$apply(); // 關鍵:將 Directive 隔離作用域變更傳播到父 Scope
      });
    }
  };
});

HTML 使用

<th class="col-md-1" sort-name="id">編號</th>
<th class="col-md-4" sort-name="name">名稱</th>

HTML Table + ng-repeat 實現數據展示與 Model 實時更新

<table id="datatableTheme" class="datatable table table-striped table-bordered table-hover">
  <thead><tr><th>編號</th><th>名稱</th><th>狀態</th><th>描述</th><th>操作</th></tr></thead>
  <tbody>
    <tr ng-repeat="item in content">
      <td ng-bind="item.id"></td>
      <td ng-bind="item.name"></td>
      <td>
        <span ng-show="item.status=='1'" class="label label-success">啟用</span>
        <span ng-show="item.status=='0'" class="label label-danger">禁用</span>
      </td>
      <td ng-bind="item.description"></td>
      <td>
        <a ng-click="edit(item.id)"><span class="label label-primary">編輯</span></a>
        <a ng-show="item.status=='0'" ng-click="enabled(item)"><span class="label label-primary">啟用</span></a>
        <a ng-show="item.status=='1'" ng-click="enabled(item)"><span class="label label-primary">禁用</span></a>
      </td>
    </tr>
  </tbody>
</table>

單行操作後 Model 更新(無需刷新)

$scope.enabled = function (theme) {
  bootbox.confirm('確認操作嗎?', function (flag) {
    if (flag) {
      var newStatus = theme.status === 1 ? 0 : 1;
      $http.post('<c:url value="/theme/enabled"/>', {id: theme.id, status: newStatus})
        .success(function (ret) {
          if (ret.err) bootbox.alert(ret.err);
          else {
            theme.status = newStatus; // 直接修改 Model,視圖自動更新
            bootbox.alert('操作成功!');
          }
        });
    }
  });
};

Directive 封裝分頁組件

.directive('pagerFooter', function () {
  return {
    restrict: 'A',
    templateUrl: '../app/template/pagerFooter.html' // 包含 ui-select 每頁條數 + uib-pagination
  };
});
<div class="box-body" pager-footer></div>

分頁模板關鍵點

  • ui-select 綁定 pageRequest.pageSize,ng-change 觸發重新查詢;
  • uib-pagination 綁定 pageRequest.pageNum,ng-change 同步觸發;
  • 模板中需聲明 <meta charset="UTF-8"> 並配置 web.xml mime-mapping 解決中文亂碼。

方案優勢總結

能力本方案DataTables / ui-grid
Model 實時更新✅ 原生 ng-bind❌ 需 API 手動刷新
復雜列邏輯/按鈕✅ ng-show/click 靈活控制⚠️ 需 render 回調
依賴體積✅ 僅 AngularJS❌ 引入重型插件
嵌套表格/在線編輯❌ 需自行擴展✅ 內置支持

對於「以讀為主、單行操作多、邏輯復雜」的後台列表頁,Directive + Service + 原生 Table 是輕量、可控、擴展性強的最佳選擇。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved