AngularJS中ng-repeat渲染完成事件[2]

作者: jicemoon | 来源:发表于2016-06-09 22:13 被阅读1528次

    ng-repeat渲染完成事件

    此方法与前篇所写不同的是, 此种写法, 每次repeat数组有更新变化(需要重新渲染)时, 都会触发此事件, 调用对应侦听, 但是, Angularjs1.3.0及其以上的版本不支持此种写法.

    核心代码

    原理是使用自定义一个过滤器, 具体代码如下:

    myApp.filter('ngRepeatFinishEveryTime', function ($timeout) {
        return function (data, eventName) {
            var me = this;
            var flagProperty = '__finishedRendering__';
            if (!data) data = {};
            if (!data[flagProperty]) {
            Object.defineProperty(data, flagProperty, {
                enumerable: false,
                configurable: true,
                writable: false,
                value: {}
            });
            $timeout(function () {
                    delete data[flagProperty];
                    me.$emit(eventName ? eventName : "ngRepeatFinishEveryTime");
                }, 0, false);
            }
            return data;
        };
    });
    

    实例

    下面是具体用法实例:

    <!DOCTYPE html>
    <html lang="en">
      <head>
        <meta charset="UTF-8">
        <style>
          .container { width: 600px; margin: auto; }
          .container > div { padding: 15px; background-color: #6D6D6D; color: #ffffff; }
          table { width: 100%; border: none; border-padding: 0; border-spacing: 0; }
          table thead{background-color: #c9e4ec;}
          table td { text-align: center; }
          table td .button { cursor: pointer; color: #571d00; font-weight: bold; }
          table tr { height: 2.5em; vertical-align: middle;}
          table tbody tr:nth-child(2n+1) { background-color: #f0f0f0; }
          table tbody tr:nth-child(2n) { background-color: #f0e0ff; }
          table tfoot { background-color: #ffd9c2; }
        </style>
        <title></title>
        <script src="http://apps.bdimg.com/libs/angular.js/1.2.9/angular.min.js"></script>
      </head>
      <body ng-app="myApp" ng-controller="userCtrl">
        <div class="container">
          <table>
            <thead>
              <tr>
                <th>索引</th>
                <th>学号</th>
                <th>姓名</th>
                <th>性别</th>
                <th>年龄</th>
                <th>操作</th>
              </tr>
            </thead>
            <tbody repeat-id="r0">
              <tr ng-repeat="(si,stu) in students=(persons|orderBy:'sort')|ngRepeatFinishEveryTime:'studentsRepeatFinish' track by $index">
                <td ng-bind="si+1"></td>
                <td ng-bind="stu.id"></td>
                <td ng-bind="stu.name"></td>
                <td ng-bind="stu.gender"></td>
                <td ng-bind="stu.age"></td>
                <td>
                  <span class="button" ng-click="changeSort(students, si, -1, 'sort')" ng-if="!$first">上移</span>
                  <span class="split" ng-if="!$first&&!$last"></span>
                  <span class="button" ng-click="changeSort(students, si, 1, 'sort')" ng-if="!$last">下移</span>
                </td>
              </tr>
            </tbody>
            <tfoot>
              <tr>
                <td colspan="6">总数量: <span ng-bind="persons.length"></span></td>
              </tr>
            </tfoot>
          </table>
          <div>
            <p>
              <lable>姓名: <input ng-model="newStu.name" type="text"/></lable>
            </p>
            <p>
              <lable>性别: <input ng-model="newStu.gender" type="radio" name="gender" value="男"/>男   <input
                  ng-model="newStu.gender" type="radio" name="gender" value="女"/>女
              </lable>
            </p>
            <p>
              <lable>年龄: <input ng-model="newStu.age" type="number"/></lable>
            </p>
            <button ng-click="add(newStu)">添加</button>
          </div>
        </div>
        <script>
          var myApp = angular.module('myApp', []);
          myApp.filter('ngRepeatFinishEveryTime', function ($timeout) {
            return function (data, eventName) {
              var me = this;
              var flagProperty = '__finishedRendering__';
              if (!data) data = {};
              if (!data[flagProperty]) {
                Object.defineProperty(data, flagProperty, {
                  enumerable: false,
                  configurable: true,
                  writable: false,
                  value: {}
                });
                $timeout(function () {
                  delete data[flagProperty];
                  me.$emit(eventName ? eventName : "ngRepeatFinishEveryTime");
                }, 0, false);
              }
              return data;
            };
          });
          myApp.controller('userCtrl', function ($scope) {
            $scope.newStu = {
              name: "jicemoon",
              gender: "男",
              age: 19
            }
            $scope.persons = [{
              id: "161112001",
              sort: 0,
              name: "赵子龙",
              gender: "男",
              age: 18
            }, {
              id: "161112002",
              sort: 2,
              name: "吕布",
              gender: "男",
              age: 18
            }, {
              id: "161112003",
              sort: 1,
              name: "貂蝉",
              gender: "女",
              age: 18
            }, {
              id: "161112004",
              sort: 3,
              name: "孙尚香",
              gender: "女",
              age: 18
            }];
            $scope.add = function (obj) {
              obj = JSON.parse(JSON.stringify(obj));
              var lens = $scope.persons.length + 1;
              obj.id = "161112" + ("000" + lens).substring(('' + lens).length);
              obj.sort = lens - 1;
              $scope.persons.push(obj);
            }
            $scope.changeSort = function (arr, index, up, attr) {
              var temp;
              temp = arr[index].sort;
              arr[index][attr] = arr[index + up][attr];
              arr[index + up][attr] = temp;
              return false;
            };
            $scope.$on("studentsRepeatFinish", function (repeatFinishedEvent) {
              console.log("data update & repeat render complete");
            })
          })
        </script>
      </body>
    </html>
    

    完整实例, 请点击一下链接进行下载
    链接: http://pan.baidu.com/s/1c7eRRg 密码: 34gp

    相关文章

      网友评论

      • 帅得不够明显:Angularjs1.3.0及其以上的版本 支持的写法有吗
      • 21da7f7b7f76:有段代码有点问题,“var me = this;”这里不太对,这里this有可能不是当前scope,我的1.4.8版本是报错,需要将scope传递进去,才可以调用$emit. 另外这个有点弊端,就是事件触发的次数会很多,只要这个ngrepeat的子项发生了重绘或者重排都会触发这个事件,会很严重影响性能。
        帅得不够明显:Angularjs1.3.0及其以上的版本 支持的写法有吗
        jicemoon:@堕落天使的 上面有些 Angularjs1.3.0及其以上的版本不支持此种写法

      本文标题:AngularJS中ng-repeat渲染完成事件[2]

      本文链接:https://www.haomeiwen.com/subject/gbcsdttx.html