21、angular1之分页组件,包含勾选、过滤、请求服务、layui中的datetime、京东购物车、两种绑定

一、angular1之分页组件(包含勾选、过滤、请求服务)
<!DOCTYPE html>
<html  ng-app="myModel">
<head>
  <meta charset="UTF-8">
  <title>分页组件之angular1.6.2版</title>
  <script type="text/javascript" src="https://cdn.bootcss.com/angular.js/1.6.2/angular.js"></script>
  <style>
    .simpleDialog {
      position: fixed;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .simpleDialog .mask {
      position: fixed;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      background: black;
      opacity: 0.5;
    }
    .simpleDialog .content {
      position: fixed;
      background: white;
      opacity: 1;
      display: flex;
      flex-direction: column;
    }
    .simpleDialog .content .title {
      display: flex;
      background: blue;
      color: white;
      padding: 10px;
      cursor: pointer;
    }
    .simpleDialog .content .title .titleText {
      flex: 1;
    }
    .simpleDialog .content .title .titleCross {
      width: 10px;
      padding: 0 5px;
    }
    .simpleDialog .content .tip {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .simpleDialog .content .conform {
      display: flex;
      justify-content: center;
      padding: 10px;
      background: blue;
    }
    .complexDialog {
      position: fixed;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .complexDialog .mask {
      position: fixed;
      width: 100%;
      height: 100%;
      top: 0;
      left: 0;
      background: black;
      opacity: 0.5;
    }
    .complexDialog .content {
      position: fixed;
      background: white;
      opacity: 1;
      display: flex;
      flex-direction: column;
    }
    .complexDialog .content .title {
      display: flex;
      background: blue;
      color: white;
      padding: 10px;
      cursor: pointer;
    }
    .complexDialog .content .title .titleText {
      flex: 1;
    }
    .complexDialog .content .title .titleCross {
      width: 10px;
      padding: 0 5px;
    }
    .complexDialog .content .tip {
      flex: 1;
      display: flex;
      align-items: center;
      justify-content: center;
    }
    .complexDialog .content .conform {
      display: flex;
      justify-content: center;
      padding: 10px;
      background: blue;
    }
    table {
      border-collapse: collapse;
      border: 1px solid #cbcbcb;
    }
    table td,
    table th {
      padding: 5px;
      border: 1px solid #cbcbcb;
    }
    table thead {
      background-color: #e0e0e0;
      color: #000;
      text-align: left;
    }
    .filter {
      width: 998px;
      border: 1px solid gray;
      padding: 10px 0px;
    }
    .filter .line {
      display: flex;
    }
    .filter .line .group {
      width: 330px;
    }
    .filter .line .group .label {
      display: inline-block;
      width: 120px;
      height: 24px;
      line-height: 24px;
      text-align: right;
    }
    .filter .line .group .input {
      display: inline-block;
      width: 180px;
      height: 24px;
      line-height: 24px;
      border-radius: 3px;
    }
    .filter .line .group .select {
      display: inline-block;
      width: 188px;
      height: 26px;
      line-height: 26x;
      border-radius: 3px;
    }
    .wholeCircle {
      position: fixed;
      width: 100%;
      height: 100%;
      left: 0;
      top: 0;
      background: rgb(145, 138, 138);
      opacity: 0.5;
      z-index: 100;
      user-select: none;
      display: flex;
      justify-content: center;
      align-items: center;
    }
    .wholeCircle .content {
      background: #fff;
      border-radius: 5px;
      overflow: hidden;
      z-index: 101;
      box-shadow: 5px 2px 6px #000;
      width: 100px;
      display: flex;
      flex-direction: column;
      align-items: center;
    }
    @keyframes customCircle {
      0% {
        transform: rotate(0deg);
      }
      100% {
        transform: rotate(-360deg);
      }
    }
    .circle {
      animation: customCircle 1s infinite linear;
    }
  </style>
</head>
<body>
  <div ng-controller="thisCtrl">
    <div>
      <div >
        <button
          
          ng-click="divideDatas.getResultOfCheckAndFilter(divideDatas.isShowFilter,divideDatas.isUseFilter,divideDatas.filterOptions)"
        >
          获取勾选和过滤结果
        </button>
        <span ng-bind="divideDatas.toServerDatas"></span>
      </div>
      <div >
        <img
          src="{{checkDatas.stateAllPages&&checkDatas.allExcludedIds.length===0?checkImg.yes:checkImg.no}}"
          ng-click="checkDatas.clickAllPages(divideDatas.tableDatas)"
        />
        <span ng-bind="checkDatas.textAllPages"></span>
      </div>
      <div >
        <button ng-click="divideDatas.toggleShowFilter()">
          {{divideDatas.isShowFilter?'关闭过滤':'使用过滤'}}
        </button>
        <button ng-click="divideDatas.emptyFilterOptions({value5:'已读后台'})">
          清空过滤
        </button>
        <button ng-click="divideDatas.request(1)">刷新</button>
      </div>
      <div
        
        class="filter"
        ng-show="divideDatas.isShowFilter"
      >
        <div class="line">
          <div class="group">
            <label class="label">标签</label>
            <input
              class="input"
              type="text"
              ng-model="divideDatas.filterOptions.value1"
            />
          </div>
          <div class="group">
            <label class="label">这就是长标签</label>
            <input
              class="input"
              type="text"
              ng-model="divideDatas.filterOptions.value2"
            />
          </div>
          <div class="group">
            <label class="label">标签</label>
            <input
              class="input"
              type="text"
              ng-model="divideDatas.filterOptions.value3"
            />
          </div>
        </div>
        <div class="line" >
          <div class="group">
            <label class="label">这就是长标签</label>
            <input
              class="input"
              type="text"
              ng-model="divideDatas.filterOptions.value4"
            />
          </div>
          <div class="group">
            <label class="label">下拉框</label>
            <select
              class="select"
              ng-model="divideDatas.filterOptions.value5"
              ng-options="item.back as item.front for item in resultDo"
            ></select>
          </div>
          <div class="group">
            <label class="label"></label>
            <button
              
              ng-click="divideDatas.useFilter()"
            >
              过滤
            </button>
          </div>
        </div>
      </div>
      <table >
        <thead>
          <tr>
            <th>
              <img
                src="{{checkDatas.stateThisPage?checkImg.yes:checkImg.no}}"
                ng-click="checkDatas.clickThisPage(divideDatas.tableDatas,divideDatas.allItemsNum)"
              />
            </th>
            <th>序号</th>
            <th>数据1</th>
            <th>数据2</th>
            <th>数据3</th>
            <th>数据4</th>
            <th>数据5</th>
            <th>数据6</th>
          </tr>
        </thead>
        <tbody>
          <tr ng-repeat="data in divideDatas.tableDatas track by $index">
            <td>
              <img
                src="{{data.state?checkImg.yes:checkImg.no}}"
                ng-click="checkDatas.clickSingleItem(data,divideDatas.tableDatas,divideDatas.allItemsNum)"
              />
            </td>
            <td ng-bind="(divideDatas.nowPageNum-1)*10 + ($index+1)"></td>
            <td ng-bind="data.key1"></td>
            <td ng-bind="data.key2"></td>
            <td ng-bind="data.key3"></td>
            <td ng-bind="data.key4"></td>
            <td ng-bind="data.key5"></td>
            <td ng-bind="data.key6"></td>
          </tr>
        </tbody>
      </table>
      <divide-page
        divide-datas="divideDatas"
        check-datas="checkDatas"
      ></divide-page>
    </div>
  </div>
</body>
<script>
  var app = angular.module('myModel', []);
  app.controller('thisCtrl', function ($scope,checkImg) {
    $scope.modelData = {
      value: 5
    };
    $scope.change = function (value) {
      console.log(value);
    };
    $scope.submit = function () {
      console.log('此处向后台发送请求');
    };
    $scope.requiredDataSimple = {
      simpleDialogTitleId: 'wholeTitleId',
      simpleDialogContentId: 'wholeContentId'
    };
    $scope.clickButtonSimple = function () {
      $scope.requiredDataSimple.isShow = true;
      $scope.requiredDataSimple.width = '600px';
      $scope.requiredDataSimple.title = '详情';
      $scope.requiredDataSimple.tip = '提交失败';
      $scope.requiredDataSimple.zIndex = 10;
    };
    $scope.requiredDataComplex = {
      complexDialogTitleId: 'wholeTitleId1',
      complexDialogContentId: 'wholeContentId1'
    };
    $scope.clickButtonComplex = function () {
      $scope.requiredDataComplex.isShow = true;
      $scope.requiredDataComplex.width = '1060px';
      $scope.requiredDataComplex.height = '700px';
      $scope.requiredDataComplex.title = '详情';
      $scope.requiredDataComplex.zIndex = 10;
      $scope.requiredDataComplex.cancel = function () {
        console.log('cancel');
      };
    };
    $scope.checkImg = checkImg;
    //<part-circle is-show='thisCircle'></part-circle>
    $scope.thisCircle = { isShow : false };
    $scope.array=[true,true,true,true,true];
    $scope.divideDatas = {
      //1、请求配置1(路由和方式)
      url: '',
      method: 'post',
      //2、请求配置2(请求参数的key,前端通过这个配置,发送数据给后台)
      nowPageNumToServer:'nowPageNumToServer', //发送给后台的当前页码key
      allPagesNumToServer:'allPagesNumToServer', //发送给后台的所有页页数key
      allItemsNumToServer:'allItemsNumToServer', //发送给后台的所有页数据数key
      eachPageItemsNumToServer:'eachPageItemsNumToServer', //发送给后台的每页最多数据数key
      //3、响应配置(返回数据的key,前端通过这个配置,获取后台的数据)
      nowPageNumFromServer: 'nowPageNumFromServer', //来自服务器的当前页码key
      allPagesNumFromServer:'allPagesNumFromServer', //来自服务器的所有页页数key
      allItemsNumFromServer:'allItemsNumFromServer', //来自服务器的所有页数据数key
      eachPageItemsNumFromServer:'eachPageItemsNumFromServer', //来自服务器的每页最多数据数key
      tableDatasKey: 'tableDatasArray', //来自服务器的表格数据key
      //4、分页初始化配置(分页在本页面首次渲染时,使用该数据)
      nowPageNum: 0, //当前页数
      allPagesNum: 0, //所有页数
      allItemsNum: 0, //所有页所有条目数
      eachPageItemsNum: 10, //每页展示条目数
      //5、初始化以下数据,供页面使用(前端根据需要决定,不受后台影响)
      dataOrParams: 'data', //参数放在哪个配置下,只有data和Params两个选择
      extraParams: {}, //页码、页条目数、过滤条件外的参数,调用divideDatas.request函数,重新渲染页面。
      filterOptions: {}, //过滤条件
      isShowFilter: false, //是否显示过滤条件。有时默认false时,显示一部分过滤条件,点击“展开”后,显示剩余过滤条件
      isUseFilter: false, //是否使用过滤条件。点击过滤后,才使用过滤条件。
      isAbandonInit: false, //是否放弃初始化组件
      partCircle: false, //把当前页控制局部转圈隐现的变量告诉cyRequest
      isUsePartCircle: false, //是否使用局部转圈
      isUseOneCircle: false, //是否使用单个全局转圈
      isUseManyCircle: false, //是否使用多个全局转圈
      frontMoreText:  '', //('文字 ')或者("文字 "+result.numOne+" 文字 "),
      totalText: '共', //,
      totalUnit: '条', //总数据的单位
      backMoreText: '', //(' 文字')或者("文字 "+result.numThree+" 文字"),
      //6、以下是现成方法,调用即可
      //过滤条件打开或关闭时执行的函数
    };
    $scope.resultDo = [
      { front: '全部前端', back: '全部后台' },
      { front: '已读前端', back: '已读后台' },
      { front: '未读前端', back: '未读后台' }
    ];
    $scope.divideDatas.filterOptions.value5 = '已读后台';
    $scope.checkDatas = {
        idKey: 'id', //每条数据的唯一标志
        stateThisPage: false, //当前页所有项是否全选
        allIncludedIds: [], //所有被选中数据的ID构成的数组
        allExcludedIds: [], //所有没被选中数据的ID构成的数组
        textAllPages: '全选未启用,没有选择任何项!', //复选框被点击后的提示文字。
        stateAllPages: false, //复选框被点击后的提示文字。
        isAbandonChecklist: false,
        
      };
  });
  app.factory('checkImg', function () {
    return {
      yes:
        'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAADqADAAQAAAABAAAADgAAAAC98Dn6AAAA+UlEQVQoFZWSMU4DMRBF/584G7QSRcIxuAZKEykNEiUVHVTQRaKh4AIcgAvQpkukVDlBOAYNSGSlXXuwpViyYYFdS9aMZ/6bsezh5HZ3T2KhqkfosEhWqnjkyd1u3xWKdQMsfaEAB0Zilf8swfdU0w0klmpGpz1BvpbHcklbPf8Okts0CfJtWBTz/Yc++Jc8S3PZVQfKGwiuvMD6XYsMzm1dT/1jXKdQ8E0asHRrAzOzbC6UGINWHPQp1UQ/6wjF2LpmJSKfhti4Bi8+lhWP4I+gAqV1uqSi8j9WRuF3m3eMWVUJBeKxzUoYn7bEX7HDyPmB7QEHbRjyL+/+VnuXDUFOAAAAAElFTkSuQmCC',
      no:
        'data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAA4AAAAOCAYAAAAfSC3RAAAAAXNSR0IArs4c6QAAAERlWElmTU0AKgAAAAgAAYdpAAQAAAABAAAAGgAAAAAAA6ABAAMAAAABAAEAAKACAAQAAAABAAAADqADAAQAAAABAAAADgAAAAC98Dn6AAAAbklEQVQoFWM8c+ZMLQMDQxUQcwAxMeAHUFEbC5CoYmNj02ZmZn5FjK6/f/+K/fr16ypIIwdIk7a29hdiNF69ehWkjIOJGMXY1IxqxBYqULEhFDiglPMDlIygKQKPryBSILUgPSCNbaC0B6RJSuQAbowizhJuOsAAAAAASUVORK5CYII='
    };
  });
  app.factory('cyRequest', function ($http, wholeCircle) {
    function thisHttp(clientDatas, deferred) {
      var toServerDatas = {
        method: clientDatas.method,
        url: clientDatas.url
      };
      var dataOrParams = clientDatas.dataOrParams || 'data';
      toServerDatas[dataOrParams] = clientDatas.AllParams;
      if (clientDatas.responseType) {
        toServerDatas.responseType = clientDatas.responseType;
      }
      if (clientDatas.isUsePartCircle) {
        clientDatas.partCircle.isShow = true;
      }
      if (clientDatas.isUseOneCircle) {
        wholeCircle.isShow = true;
      }
      if (clientDatas.isUseManyCircle) {
        wholeCircle.isShow = true;
      }
      $http(toServerDatas)
        .then(function (result) {
          //result.status(不是result.clientDatas.status)===200时进入这里,否则进入catch
          if (clientDatas.isDirectUseDatas) {
            deferred.resolve(result);
            //如果出错就一直转圈,那么可以把finally里的代码放到这里
          } else {
            if (result.clientDatas.status === 1000) {
              //全局弹窗告知结果
            } else if (result.clientDatas.status === 0) {
              //全局弹窗告知结果
            } else {
              deferred.resolve(result.clientDatas);
              //如果出错就一直转圈,那么可以把finally里的代码放到这里
            }
          }
        })
        .catch(function (err) {
          deferred.reject(err);
        })
        .finally(function () {
          if (clientDatas.isUsePartCircle) {
            clientDatas.partCircle.isShow = false;
          }
          if (clientDatas.isUseOneCircle) {
            wholeCircle.isShow = false;
          }
          if (clientDatas.isUseManyCircle) {
            // $scope.array=[true,true,true,true,true];
            // wholeCircle: {
            //   array: $scope.array,
            //   index: 0
            // }, 
            var flag = false;
            clientDatas.wholeCircle.array[clientDatas.wholeCircle.index]=false;
            for(var i=0; i<clientDatas.wholeCircle.array.length; i++){
              if(clientDatas.wholeCircle.array[i]) flag = true
            }
            if(!flag) wholeCircle.isShow = false;
          }
        });
    }
    return function (clientDatas) {
      var deferred = $q.defer();
      if (clientDatas.warn) {
        //全局弹窗告知结果
        $scope.requiredData = {
          isShow: true,
          width: '400px',
          title: '详情',
          tip: '确认提交',
          submit: function () {
            thisHttp(clientDatas, deferred);
          }
        };
      } else {
        thisHttp(clientDatas, deferred);
      }
      return deferred.promise;
    };

    // $scope.array=[true,true,true,true,true];
    // cyRequest({
    //   method: 'post',
    //   url: 'a/b/c',
    //   warn: '确定提交吗?',
    //   dataOrParams: 'data',
    //   AllParams: {key:1},
    //   partCircle: $scope.thisCircle,//把当前页控制局部转圈隐现的变量告诉cyRequest
    //   isUsePartCircle: true,//是否使用局部转圈
    //   isUseOneCircle: true,//是否一个请求使用一个全局转圈
    //   isUseManyCircle: true,//是否多个请求共用一个全局转圈
    //   wholeCircle: {//多个请求共用一个全局转圈
    //     array: $scope.array,
    //     index: 0
    //   },
    // })
  });
  app.directive('dividePage', function () {
    var html = `
      <div ng-show="divideDatas.allPagesNum>=1" >
        <div>
          <div>
            <button 
              ng-hide="divideDatas.allPagesNum<=10" 
              ng-click="clickDividePage('front') " 
              ng-disabled="divideDatas.nowPageNum===1"
            >上一页</button>
            <button 
              ng-repeat="num in divideArray track by $index" 
              ng-bind="num" 
              ng-click="clickDividePage(num) " 
              ng-color':'red'}:{'color':'black'}" 
              ng-disabled="num==='...'"
              
            >
            </button>
            <button 
              ng-hide="divideDatas.allPagesNum<=10" 
              ng-click="clickDividePage('back') "  
              ng-disabled="divideDatas.nowPageNum===divideDatas.allPagesNum"
            >下一页</button>
          </div>
          
        </div>
        <div >
          <div >
            <span>转到第</span>
            <input type="text" ng-model="customString" ng-keydown="clickDividePage('leap',$event)" >
            <span>页</span>
            <button ng-click="clickDividePage('leap',{which:13})">Go</button>
          </div>
          <div>
            <span>每页显示</span>
            <select ng-model="divideDatas.eachPageItemsNum" ng-options="item.back as item.front for item in numOptions" ng-disabled="true"></select>
            <span>条,</span>
          </div>
          <div>
            <span ng-bind="divideDatas.frontMoreText"></span>
            <span ng-bind="divideDatas.totalText"></span>
            <span ng-bind="divideDatas.allItemsNum"></span>
            <span ng-bind="divideDatas.totalUnit"></span>
            <span ng-bind="divideDatas.backMoreText"></span>
          </div>
        </div>   
      </div> 
    `;
    return {
      restrict: 'E',
      template: html,
      scope: {
        divideDatas: '=divideDatas',
        checkDatas: '=checkDatas'
      },
      controller: function ($scope, $timeout /* , cyRequest */) {
        $scope.checkDatas = $scope.checkDatas||{};
        $scope.divideDatas = $scope.divideDatas||{};
        $scope.request = $scope.divideDatas.request = function (pageNum) {
          var AllParams = $scope.getResultOfCheckAndFilter(
            $scope.divideDatas.isShowFilter,
            $scope.divideDatas.isUseFilter,
            $scope.divideDatas.filterOptions,
            $scope.divideDatas.extraParams,
          );
          AllParams.nowPageNum = pageNum;
          // cyRequest({
          //   url: $scope.divideDatas.url,
          //   method: $scope.divideDatas.method,
          //   dataOrParams: $scope.divideDatas.dataOrParams,
          //   AllParams: AllParams,
          //   partCircle: $scope.divideDatas.partCircle,
          //   isUsePartCircle: $scope.divideDatas.isUsePartCircle, 
          //   isUseOneCircle: $scope.divideDatas.isUseOneCircle,
          //   isUseManyCircle: $scope.divideDatas.isUseManyCircle,
          // }).then(function () {
          var data = [];
          for (var i = 1; i <= 144; i++) {
            var obj = {
              id: 'id' + i,
              key1: '数据' + (i + 0),
              key2: '数据' + (i + 1),
              key3: '数据' + (i + 2),
              key4: '数据' + (i + 3),
              key5: '数据' + (i + 4),
              key6: '数据' + (i + 5),
              key7: '数据' + (i + 6)
            };
            data.push(obj);
          }
          var result = {
            tableDatasArray: [],
            nowPageNumFromServer: 5,
            allPagesNumFromServer: 15,
            allItemsNumFromServer: 144,
            eachPageItemsNumFromServer: 10
          };
          result.tableDatasArray = data.slice(
            (pageNum - 1) * 10,
            pageNum * 10
          );
          $scope.customString =
            pageNum || result[$scope.divideDatas.nowPageNumFromServer];
          $scope.divideDatas.nowPageNum =
            pageNum || result[$scope.divideDatas.nowPageNumFromServer];
          $scope.divideDatas.allPagesNum =
            result[$scope.divideDatas.allPagesNumFromServer];
          $scope.divideDatas.allItemsNum =
            result[$scope.divideDatas.allItemsNumFromServer];
          $scope.divideDatas.eachPageItemsNum =
            result[$scope.divideDatas.eachPageItemsNumFromServer];
          $scope.divideDatas.tableDatas =
            result[$scope.divideDatas.tableDatasKey];
          if(angular.isFunction($scope.divideDatas.executeOnceBefore)){
            $scope.divideDatas.executeOnceBefore($scope.divideDatas.tableDatas);
            $scope.divideDatas.executeOnceBefore = null;
          }
          if(angular.isFunction($scope.divideDatas.executeEveryTrue)){
            $scope.divideDatas.executeEveryTrue($scope.divideDatas.tableDatas);
          }
          if(angular.isFunction($scope.divideDatas.executeOnceAfter)){
            $scope.divideDatas.executeOnceAfter($scope.divideDatas.tableDatas);
            $scope.divideDatas.executeOnceAfter = null;
          }
          if ($scope.checkDatas) {
            if(!$scope.checkDatas.isAbandonChecklist){
              $scope.checkDatas.signCheckbox($scope.divideDatas.tableDatas);
            }else{
              $scope.checkDatas.init();
            }
          }
          $scope.createDividePage();
          // }).catch(function(){
          //   if (angular.isFunction($scope.divideDatas.executeEveryError)) {
          //     $scope.divideDatas.executeEveryError(result);
          //   }
          // })
        };
        $scope.numOptions = [
          { back: 10, front: 10 },
          { back: 20, front: 20 },
          { back: 30, front: 30 },
          { back: 40, front: 40 },
          { back: 50, front: 50 }
        ];
        $scope.getResultOfCheckAndFilter = $scope.divideDatas.getResultOfCheckAndFilter = function (
          isShowFilter,
          isUseFilter,
          filterOptions,
          extraParams
        ) {
          var checkboxDatas;
          var toServerDatas;
          extraParams = extraParams||{};
          if (!$scope.checkDatas.stateAllPages) {
            if ($scope.checkDatas.allIncludedIds.length === 0) {
              //return 弹窗告知:没有勾选项
            }
            checkboxDatas = {
              isSelectAll: false,
              allIncludedIds: $scope.checkDatas.allIncludedIds
            };
          } else {
            checkboxDatas = {
              isSelectAll: true,
              allExcludedIds: $scope.checkDatas.allExcludedIds
            };
          }
          if (isShowFilter||isUseFilter) {
            toServerDatas = angular.merge(
              {},
              { checkboxDatas: checkboxDatas },
              { filterOptions: filterOptions },
              extraParams
            );
          } else {
            toServerDatas = angular.merge({}, { checkboxDatas: checkboxDatas }, extraParams);
          }
          this.toServerDatas = toServerDatas; //这行代码在实际项目中不需要
          return toServerDatas;
        };
        $scope.createDividePage = function () {
          var divideArray = [];
          var allPagesNum = $scope.divideDatas.allPagesNum;
          var nowPageNum = $scope.divideDatas.nowPageNum;
          console.log( allPagesNum    )
          console.log( nowPageNum    )
          if (allPagesNum >= 1 && allPagesNum <= 10) {
            for (var i = 1; i <= allPagesNum; i++) {
              divideArray.push(i);
            }
          } else if (allPagesNum >= 11) {
            if (nowPageNum > 6) {
              divideArray.push(1);
              divideArray.push(2);
              divideArray.push(3);
              divideArray.push('...');
              divideArray.push(nowPageNum - 1);
              divideArray.push(nowPageNum);
            } else {
              for (i = 1; i <= nowPageNum; i++) {
                divideArray.push(i);
              }
            }
            // 以上当前页的左边,以下当前页的右边
            if (allPagesNum - nowPageNum >= 6) {
              divideArray.push(nowPageNum + 1);
              divideArray.push(nowPageNum + 2);
              divideArray.push('...');
              divideArray.push(allPagesNum - 2);
              divideArray.push(allPagesNum - 1);
              divideArray.push(allPagesNum);
            } else {
              for (var i = nowPageNum + 1; i <= allPagesNum; i++) {
                divideArray.push(i);
              }
            }
          }
          $scope.divideArray = divideArray;
        };
        $scope.clickDividePage = function (stringOfNum, event) {
          var allPagesNum = $scope.divideDatas.allPagesNum;
          var nowPageNum = $scope.divideDatas.nowPageNum;
          if (stringOfNum === 'front' && nowPageNum != 1) {
            nowPageNum--;
          } else if (stringOfNum === 'back' && nowPageNum != allPagesNum) {
            nowPageNum++;
          } else if (stringOfNum === 'leap') {
            if (event.which != 13) return; //不拦截情形:(1)聚焦输入框、按“Enter”键时;(2)点击“GO”时
            var customNum = Math.ceil(parseFloat($scope.customString));
            if (customNum < 1 || customNum == 'NaN') {
              nowPageNum = 1; //不给提示
            } else if (customNum > allPagesNum) {
              nowPageNum = allPagesNum; //不给提示
            } else {
              nowPageNum = customNum;
            }
          } else {
            nowPageNum = Math.ceil(parseFloat(stringOfNum));
          }
          $scope.customString = nowPageNum;
          $scope.request(nowPageNum);
        };
        $scope.checkDatas.init = function () {
          //点击“刷新”、“过滤”、“清除过滤”时执行
          this.idKey = idKey ? idKey : 'id';
          this.allIncludedIds = [];
          this.allExcludedIds = [];
          this.textAllPages = '全选未启用,没有选择任何项!';
          this.stateAllPages = false;
          this.stateThisPage = false;
        };
        $scope.checkDatas.clickAllPages = function (itemArray) {
          //所有页所有条目全选复选框被点击时执行的函数
          if (this.stateAllPages) {
            if (this.allExcludedIds.length > 0) {
              this.stateAllPages = true;
              this.stateThisPage = true;
              this.textAllPages = '全选已启用,没有排除任何项!';
              angular.forEach(itemArray, function (item) {
                item.state = true;
              });
            } else if (this.allExcludedIds.length == 0) {
              this.stateAllPages = false;
              this.stateThisPage = false;
              this.textAllPages = '全选未启用,没有选择任何项!';
              angular.forEach(itemArray, function (item) {
                item.state = false;
              });
            }
          } else {
            this.stateAllPages = true;
            this.stateThisPage = true;
            this.textAllPages = '全选已启用,没有排除任何项!';
            angular.forEach(itemArray, function (item) {
              item.state = true;
            });
          }
          this.allExcludedIds = [];
          this.allIncludedIds = [];
        };
        $scope.checkDatas.clickThisPage = function (itemsArray, allItemsNum) {
          //当前页所有条目全选复选框被点击时执行的函数
          var that = this;
          this.stateThisPage = !this.stateThisPage;
          angular.forEach(itemsArray, function (item) {
            item.state = that.stateThisPage;
            if (item.state) {
              that.delID(item[that.idKey], that.allExcludedIds);
              that.addID(item[that.idKey], that.allIncludedIds);
            } else {
              that.delID(item[that.idKey], that.allIncludedIds);
              that.addID(item[that.idKey], that.allExcludedIds);
            }
          });
          if (this.stateAllPages) {
            if (this.stateThisPage && this.allExcludedIds.length === 0) {
              this.textAllPages = '全选已启用,没有排除任何项!';
            } else {
              this.textAllPages =
                '全选已启用,已排除' +
                this.allExcludedIds.length +
                '项!排除项的ID为:' +
                this.allExcludedIds;
            }
          } else {
            if (!this.stateThisPage && this.allIncludedIds.length === 0) {
              this.textAllPages = '全选未启用,没有选择任何项!';
            } else {
              this.textAllPages =
                '全选未启用,已选择' +
                this.allIncludedIds.length +
                '项!选择项的ID为:' +
                this.allIncludedIds;
            }
          }
        };
        $scope.checkDatas.clickSingleItem = function (item, itemsArray, allItemsNum) {
          //当前页单个条目复选框被点击时执行的函数
          var that = this;
          item.state = !item.state;
          if (item.state) {
            this.stateThisPage = true;
            this.addID(item[this.idKey], this.allIncludedIds);
            this.delID(item[this.idKey], this.allExcludedIds);
            angular.forEach(itemsArray, function (item) {
              if (!item.state) {
                that.stateThisPage = false;
              }
            });
          } else {
            this.stateThisPage = false;
            this.addID(item[this.idKey], this.allExcludedIds);
            this.delID(item[this.idKey], this.allIncludedIds);
          }
          if (this.stateAllPages) {
            if (this.stateThisPage && this.allExcludedIds.length === 0) {
              this.textAllPages = '全选已启用,没有排除任何项!';
            } else {
              this.textAllPages =
                '全选已启用,已排除' +
                this.allExcludedIds.length +
                '项!排除项的ID为:' +
                this.allExcludedIds;
            }
          } else {
            if (!this.stateThisPage && this.allIncludedIds.length === 0) {
              this.textAllPages = '全选未启用,没有选择任何项!';
            } else {
              this.textAllPages =
                '全选未启用,已选择' +
                this.allIncludedIds.length +
                '项!选择项的ID为:' +
                this.allIncludedIds;
            }
          }
        };
        $scope.checkDatas.signCheckbox = function (itemsArray) {
          //标注当前页被选中的条目,在翻页成功后执行。
          var that = this;
          if (this.stateAllPages) {
            this.stateThisPage = true;
            angular.forEach(itemsArray, function (item) {
              var thisID = item[that.idKey];
              var index = that.allExcludedIds.indexOf(thisID);
              if (index > -1) {
                item.state = false;
                that.stateThisPage = false;
              } else {
                item.state = true;
              }
            });
          } else {
            this.stateThisPage = true;
            angular.forEach(itemsArray, function (item) {
              var thisID = item[that.idKey];
              var index = that.allIncludedIds.indexOf(thisID);
              if (index === -1) {
                item.state = false;
                that.stateThisPage = false;
              }else{
                item.state = true;
              }
            });
          }
        };
        $scope.checkDatas.addID = function (id, idArray) {
          var index = idArray.indexOf(id);
          if (index === -1) {
            idArray.push(id); //如果当前页的单项既有勾选又有非勾选,这时勾选当前页全选,需要这个判断,以免重复添加
          }
        };
        $scope.checkDatas.delID = function (id, idArray) {
          var index = idArray.indexOf(id);
          if (index > -1) {
            idArray.splice(index, 1);
          }
        };
        
        $scope.divideDatas.toggleShowFilter = function () {
          this.isUseFilter = false;
          this.isShowFilter = !this.isShowFilter;
          if (!this.isShowFilter) {
            this.request(1);
          }
        };
        //点击过滤时执行的函数
        $scope.divideDatas.useFilter = function () {
          this.isUseFilter = true;
          this.request(1);
        };
        //清空过滤条件时执行的函数
        //清空选项时,所有值恢复成默认
        $scope.divideDatas.emptyFilterOptions = function () {
          var that = this;
          angular.forEach(that.filterOptions, function (value, key) {
            if(that.filterOptionsInit[key]){
              that.filterOptions[key]= that.filterOptionsInit[key]
            }else{
              that.filterOptions[key] = undefined;
            }
          });
          this.request(1);
        };
        if (!$scope.divideDatas.isAbandonInit) {
          $scope.request(1);
        }
      }
    };
  }); 
  </script>
</html>

二、angular1里用layui中的datetime示例
来源:https://www.layui.com/doc/modules/laydate.html#type
<dir-datepicker date-model="pagin_init.filter_option.beginTime"></dir-datepicker>
(function () {
  angular
    .module('common-dir')
    .directive('dirDatepicker', function () {
      return {
        restrict: 'E',
        template: '<input  type="text" class="form-control common-select-time" ng-model="dateModel"  >,
        replace: true,
        scope: {
          format: '@',
          dateModel: '=',
          isDisable: '=',
          callback: '&'
        },
        controller: function ($scope) {
          $scope.dateInputId = 'id' + Math.random();
          angular.element(document).ready(function () {
            var config = {
              elem: '#' + $scope.dateInputId,
              theme: '#007bff',
              trigger: 'click',
              done: function (value) {
                $scope.dateModel = value;
                angular.isFunction($scope.callback) ? $scope.callback() : '';
              }
            };
            if ($scope.format) {
              config.format = $scope.format;//自定义格式
            } else {
              config.type = 'datetime';//控件选择类型
            }
            laydate.render(config);
          });
        },
        link: function () {
        }
      };
    });
})();
控件选择完毕后的回调
点击日期、清空、现在、确定均会触发。回调返回三个参数,分别代表:生成的值、日期时间对象、结束的日期时间对象
laydate.render({
  elem: '#test',
  done: function(value, date, endDate){
    console.log(value); //得到日期生成的值,如:2017-08-18
    console.log(date); //得到日期时间对象:{year: 2017, month: 8, date: 18, hours: 0, minutes: 0, seconds: 0}
    console.log(endDate); //得结束的日期时间对象,开启范围选择(range: true)才会返回。对象成员同上。
  }
});

三、agular1实现京东购物车
<!DOCTYPE html>
<html >
<head>
  <meta charset="UTF-8">
  <title>Title</title>
  <link rel="stylesheet" href="https://cdn.bootcss.com/bootstrap/4.1.1/css/bootstrap.css">
  <script type="text/javascript" src="https://cdn.bootcss.com/angular.js/1.5.8/angular.js"></script>
</head>
<body ng-app="myApp" ng-controller="myCtrl"  ng-cloak >
  <div>
    <label>全选</label>
    <input type="checkbox" ng-model="allCheck" ng-click="allChecked()">
    <span>总金额:{{ totalValue | currency:"¥"}}</span>
  </div>
  <table class="table table-bordered" ng-repeat="oneShop in allShops track by $index"  ng-init="outerIndex = $index" >
    <thead>
    <tr>
      <th><input type="checkbox" ng-model="oneShop.checked" ng-click="shopChecked(oneShop,allShops)"></th>
      <th colspan="7">{{oneShop.shopName}}</th>
    </tr>
    </thead>
    <tbody>
      <tr ng-repeat="goods in oneShop.shopGoods track by $index"  ng-init="innerIndex = $index">
        <td><input type="checkbox" ng-model="goods.checked" ng-click="goodsChecked(goods,oneShop.shopGoods,oneShop,allShops)"></td>
        <td>{{goods.goodsName}}</td>
        <td>{{goods.price}}元/件,共</td>
        <td><span ng-click="changeNumber(goods,oneShop.shopGoods,oneShop,allShops,'+')" >+</span></td>
        <td>{{goods.number}}</td>
        <td><span ng-click="changeNumber(goods,oneShop.shopGoods,oneShop,allShops,'-')" >-</span></td>
        <td>件,本商品共: {{goods.singleMoney}}元</td>
        <td ng-click="delete(innerIndex,outerIndex,oneShop,allShops)" >删除</td>
      </tr>
    </tbody>
</table>
</body>
</html>
<script>
var myApp = angular.module("myApp", []);
myApp.controller("myCtrl", function ($scope) {
  $scope.allShops = [
    {
      shopName: "专卖店一:北京鸡",
      shopGoods: [
        {
          goodsName: "北京鸡1",
          picture: "images/allShops_01.jpg",
          price: 150.0,
          singleMoney: 150.0,
          number:1
        },
        {
          goodsName: "北京鸡2",
          picture: "images/allShops_02.jpg",
          price: 119.0,
          singleMoney: 119.0,
          number:1
        },
        {
          goodsName: "北京鸡3",
          picture: "images/allShops_03.jpg",
          price: 101.0,
          singleMoney: 101.0,
          number:1
        },
      ],
    },
    {
      shopName: "专卖店二:北京鸭",
      shopGoods: [
        {
          goodsName: "北京鸭1",
          picture: "images/allShops_04.jpg",
          price: 89.0,
          singleMoney: 89.0,
          number:1
        },
        {
          goodsName: "北京鸭2",
          picture: "images/allShops_05.jpg",
          price: 99.0,
          singleMoney: 99.0,
          number:1
        },
      ],
    },
    {
      shopName: "专卖店三:北京鹅",
      shopGoods: [
        {
          goodsName: "北京鹅1",
          picture: "images/allShops_06.jpg",
          price: 289.0,
          singleMoney: 289.0,
          number:1
        },
      ],
    },
  ];
  $scope.totalValue = 0;
  //增减该件商品
  $scope.changeNumber = function (goods, shopGoods, oneShop, allShops, type) {
    if(type === '-'){
      goods.number--;
      if(goods.number <= 1) goods.number = 1;
    }else if(type === '+'){
      goods.number++;
    }
    goods.singleMoney = goods.price * goods.number;
    goods.checked = true;
    $scope.goodsChecked(goods, shopGoods, oneShop, allShops);
    $scope.getTotalMoney();
  };
  //删除该件商品
  $scope.delete = function (innerIndex, outerIndex, oneShop, allShops) {
    oneShop.shopGoods.splice(innerIndex, 1);
    if (oneShop.shopGoods.length <= 0) {
      allShops.splice(outerIndex, 1);
    }
    $scope.getTotalMoney();
  };
  /*所有商品总金额计算*/
  $scope.getTotalMoney = function () {
    var total = 0;
    angular.forEach($scope.allShops, function (outerItem) {
      angular.forEach(outerItem.shopGoods, function (innerItem) {
        if (innerItem.checked) {
          total += innerItem.price * innerItem.number;
        }
      });
    });
    $scope.totalValue = total;
  };
  /*勾选单件商品*/
  $scope.goodsChecked = function (
    goods,
    shopGoods,
    oneShop,
    allShops
  ) {
    var flag = true;
    if (goods.checked) {
      angular.forEach(shopGoods, function (innerItem) {
        if (!innerItem.checked) {
          flag = false;
        }
      });
    } else {
      $scope.allCheck = false;
      oneShop.checked = false;
      flag = false;
    }
    if (flag) {
      oneShop.checked = true;
      $scope.allCheck = true;
      angular.forEach(allShops, function (outerItem) {
        if (!outerItem.checked) {
          flag = false;
        }
      });
    }
    $scope.getTotalMoney();
  };
  /*勾选单家商铺*/
  $scope.shopChecked = function (oneShop, allShops) {
    if (oneShop.checked) {
      var flag = true;
      angular.forEach(oneShop.shopGoods, function (innerItem) {
        innerItem.checked = true;
      });
      angular.forEach(allShops, function (outerItem) {
        if (!outerItem.checked) {
          flag = false;
        }
      });
      if (flag) {
        $scope.allCheck = true;
      }
    } else {
      $scope.allCheck = false;
      angular.forEach(oneShop.shopGoods, function (innerItem) {
        innerItem.checked = false;
      });
    }
    $scope.getTotalMoney();
  };
  /*勾选全部商铺*/
  $scope.allChecked = function () {
    if ($scope.allCheck) {
      angular.forEach($scope.allShops, function (oneShop) {
        oneShop.checked = true;
        angular.forEach(oneShop.shopGoods, function (innerItem) {
          innerItem.checked = true;
        });
      });
    } else {
      angular.forEach($scope.allShops, function (oneShop) {
        oneShop.checked = false;
        angular.forEach(oneShop.shopGoods, function (innerItem) {
          innerItem.checked = false;
        });
      });
    }
    $scope.getTotalMoney();
  };
});    
</script>
 
四、angular1两种作用域绑定
angular1模块、控制器和作用域的两种绑定方式,模块不必通过ng-app关联到HTML的标签上,也不必通过angular.bootstrap()关联到HTML的标签上!
1、正常绑定 
<!DOCTYPE html>
<html ng-app="app">
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<body>
  <div>
    <div ng-controller="myCtrl">
      {{ hello }}
    </div>
  </div>
  <script type="text/javascript">
    var module = angular.module("app", []);
    module.controller("myCtrl", function ($scope) {
      //app模块的控制器(myCtrl)将作用域的hello 赋值为 "a Angular app"
      $scope.hello = "a Angular app";
    });
  </script>
</body>
</html>
2、异常绑定
<!DOCTYPE html>
<html>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<script src="http://apps.bdimg.com/libs/angular.js/1.4.6/angular.min.js"></script>
<body>
  <div >
    <div ng-controller="myCtrl">
      {{ hello }}
    </div>
  </div>
  <div >
    <div ng-controller="myCtrl">
      {{ hello }}
    </div>
  </div>
  <script type="text/javascript">
    var module1 = angular.module("test1", []);
    module1.controller("myCtrl", function ($scope) {
      //test1模块的控制器(myCtrl)将作用域的hello 赋值为 "a Angular app"
      $scope.hello = "a Angular app";
    });
    var module2 = angular.module("test2", []);
    module2.controller("myCtrl", function ($scope) {
      //test2模块的控制器(myCtrl)将作用域的hello 赋值为 "a Angular app"
      $scope.hello = " another Angular app";
    });
    /*此方法用于手动加载angularjs模板*/
    angular.bootstrap(document.getElementById("app1"), ['test1']);
    /*此方法用于手动加载angularjs模板*/
    angular.bootstrap(document.getElementById("app2"), ['test2']);
  </script>
</body>
</html>

五、两种函数传递
1、以(对象)变量传递 
<!doctype html>
<html  ng-app="appModule">
<head>
  <meta charset="UTF-8">
  <title>函数当作变量传进去</title>
</head>
<body ng-controller="myCtrl">
  <p ng-click="fnClick('我是原有标签')">点击原有标签</p>
  <my-text fn="fnClick"></my-text>
  <br/>
  <script type="text/javascript" src="https://cdn.bootcss.com/angular.js/1.5.8/angular.js"></script>
  <script>
    var app = angular.module('appModule', []);
    app.controller('myCtrl', function ($scope) {
      $scope.fnClick = function (tip) {
        alert(tip)
      }
    });
    app.directive('myText', function () {
      return {
        restrict: 'E',
        template: '<h1 ng-click="thisFn()"><span>点击自定义标签</span></h1>',
        scope: {
          fn: '='
        },
        controller: function ($scope) {
          $scope.thisFn=function(){
            $scope.fn('我是自定义标签,函数当作变量传入')
          }
        }
      }
    })
  </script>
</body>
</html>
2、以函数传递
<!doctype html>
<html  ng-app="appModule">
<head>
  <meta charset="UTF-8">
  <title>函数当作函数传进去</title>
</head>
<body ng-controller="myCtrl">
  <p ng-click="fnClick('我是原有标签','AAA')">点击原有标签</p>
  <my-text fn="fnClick(tipA,tipB)"></my-text>
  <br />
  <script type="text/javascript" src="https://cdn.bootcss.com/angular.js/1.5.8/angular.js"></script>
  <script>
    var app = angular.module('appModule', []);
    app.controller('myCtrl', function ($scope) {
      $scope.fnClick = function (tip,pit) {
        console.log(pit)
        alert(tip)
      }
    });
    app.directive('myText', function () {
      return {
        restrict: 'E',
        template: '<h1 ng-click="thisFn()"><span>点击自定义标签</span></h1>',
        scope: {
          fn: '&'
        },
        controller: function ($scope) {
          $scope.thisFn=function(){
            $scope.fn({tipA:'我是自定义标签,函数当作函数传入',tipB:'BBB'})
          }
        }
      }
    })
  </script>
</body>
</html>

六、组件渲染出错
1、添加ng-if
2、去掉无用的属性传参 
3、注入没定义的服务