专栏首页葡萄城控件技术团队AngularJS:如何使用自定义指令来取代ng-repeat

AngularJS:如何使用自定义指令来取代ng-repeat

引言

本文主要介绍了另一种即具有与ng-repeat 一样处理大量数据的绑定的功能,又具有超高的性能。

对于处理小数量,ng-repeat是非常有用的,但是如果需要处理非常大的数量集,还是采用自定义的方法更好一些。

也别是数据大多都是静态的或已预存储好的,这个时候应避免使用ng-repeat指令。

ng-repeat中的表达式和 $watch

Angular中的表达式都会创建$watch 的Scope 函数。用于监听模型变化,当你的模型部分发生变化时它会通知你。在ng-repeat指令中,如果某行数据有15列数据都绑定了表达式,如果数据有1000多行的话,那么$watch就将近15000个,这性能简直难以想象。

所以当我们想要实现ng-repeat的功能又想兼备性能,那只能另找一种方法了。

替换ng-repeat的方法

如果内容是静态的,我们不需要两种方式的绑定,只需要执行一次赋值语句{{::value}}就可以。如果anguluarJS是1.3以下的旧版本,是不支持的一次性绑定语法的。那么最好的方法就是自定义指令,换言之,静态数据可以使用一些简单的方法来格式化。

实现步骤

  • 首先创建无序列表,用于保存动态绑定的内容。

创建UL标签作为容器用于显示列表

我们选择动态加载List中的数据,首先添加div标签,并命名为"repeater-alternative"用于渲染流中。

<div>
    <ul>
        <div repeater-alternative></div>
    </ul>
</div>
  • 定义List 数据:
//示例数据
var studentsList = 
[
    {
       FirstName: "Raj,
       LastName : "B",
       Country : "India",
       BirthDate: "01/01/1990"
    },
    {
       FirstName: "Kumar,
       LastName : "S",
       Country : "India",
       BirthDate: "01/01/1990"
    },
    ..................
  ..................
  ..................
  ..................
];

$scope.collectionObject = studentsList; //分配给$scope函数
  • 实际List内容

主要目的适用于重复集合对象,并显示到列表中,所以需要制定访问循环的逻辑,并按照需求来格式化字符串。

var tableRow = "";
angular.forEach($scope.collectionObject, function (item) {
    tableRow = tableRow + ['<li>',
    '<div class="col-md-1">' + item.FirstName + '</div> ',
    '<div class="col-md-1 ">' + item.LastName + '</div> ',
    '<div class="col-md-1 ">' + item.Country+ '</div> ',
    '<div class="col-md-1 ">' + item.Id + '</div> ',
    '<div class="col-md-1 ">' + $filter('date')(item.BirthDate, 'dd-MMM-yyyy') + '</div> ',
    '</li>'].join('');
});
  • List格式化逻辑

一旦collectionObject的值已被赋给其他变量,就需要定义显示数据的表格。

  • 如何获取分配CollectionObject的时间

Angular会监控$scope变量值得改变,一旦值被修改,则$watch将被触发,所以需要将CollectionObject赋值逻辑放到$scope变量的$watch中。代码如下:

$scope.$watch($scope.object, function (oldValue, newValue) { 
})

即,当我们执行赋值语句是,Angular会处理这个事件,并格式化List的内容。

$scope.$watch('collectionObject', function (oldValue, newValue) {
    var tableRow = "";
    angular.forEach($scope.collectionObject, function (item) {
        tableRow = tableRow + ['<li>',
        '<div class="col-md-1">' + item.FirstName + '</div> ',
        '<div class="col-md-1 ">' + item.LastName + '</div> ',
        '<div class="col-md-1 ">' + item.State + '</div> ',
        '<div class="col-md-1 ">' + item.Id + '</div> ',
        '<div class="col-md-1 ">' + $filter('date')(item.BirthDate, 'dd-MMM-yyyy') + '</div> ',
        '</li>'].join('');
    });
})
  • 接下来就是将内容渲染到表格控件中,也就是HTML<DIV>repeater-alternative标签中。

首先必须理解Angular的Directive机制,简单而言,就是我们来指示Angular,当指定的变量被发现,就开始执行后台操作。

var userDirectives = angular.module([]);

userDirectives.directive('DOMElementFound', function () {
    return {
        replace: true,
        link: function ($scope, $elem, attrs) {
                  //后台处理操作        }
    }
});

我们会通知Angular,当发现"repeater-alternative" 元素,则将以下数据渲染到列表行中。代码如下:

var userDirectives = angular.module([]);

userDirectives.directive('repeaterAlternative', function () {
    return {
        replace : true,
        link: function ($scope, $elem, attrs) {

            $scope.$watch('collectionObject', function (oldValue, newValue) {
                var tableRow = "";
                angular.forEach($scope.collectionObject, function (item) {
                    tableRow = tableRow + ['<li>',
                                    '<div class="col-md-1">' + item.FirstName + '</div> ',
                                    '<div class="col-md-1 ">' + item.LastName + '</div> ',
                                    '<div class="col-md-1 ">' + item.State + '</div> ',
                                    '<div class="col-md-1 ">' + item.Id + '</div> ',
                                    '<div class="col-md-1 ">' + $filter('date')(item.BirthDate, 'dd-MMM-yyyy') + '</div> ',
                                    '</li>'].join('');
                });

                
                //If IE is your primary browser, innerHTML is recommended to increase the performance
                $elem.context.innerHTML = tableRow;
                //If IE is not your primary browser, just appending the content to the element is enough .
                //$elem.append(tableRow);
            });
        }
    }
});

总结

在本文中,主要模拟了ng-repeat的工作方式和逻辑,但只限于静态内容,所以输出结果与调用ng-repeat结果相同,但是渲染更快,因为该方法只有一种数据绑定方式和少量的$watch。

支持 AngularJS 的控件集

Wijmo 天生就支持了 AngularJS 框架,现在 Wijmo 又全球第一个支持 AngularJS 2 框架。Wijmo 中提供了大量的支持 AngularJS 及 AngularJS 2 的Demo。

Wijmo 是为企业应用程序开发而推出的一系列包含 HTML5 和 JavaScript 的开发控件集。

它包含 Wijmo 5(先进的JavaScript控件)、Wijmo 3(经典的jQuery小部件)、金融图表、FlexSheet、OLAP。无论您的应用程序是移动端、PC端、还是必须要支持IE6,Wijmo Enterprise 均能满足您的需求。

了解更多信息请访问 Wijmo官网

本文参与腾讯云自媒体分享计划,欢迎正在阅读的你也加入,一起分享。

我来说两句

0 条评论
登录 后参与评论

相关文章

  • MVC5:使用Ajax和HTML5实现文件上传功能

    引言 在实际编程中,经常遇到实现文件上传并显示上传进度的功能,基于此目的,本文就为大家介绍不使用flash 或任何上传文件的插件来实现带有进度显示的文件上传功能...

    葡萄城控件
  • 带你走近AngularJS - 体验指令实例

    带你走近AngularJS系列: 带你走近AngularJS - 基本功能介绍 带你走近AngularJS - 体验指令实例 带你走近AngularJS - 创...

    葡萄城控件
  • ASP.NET MVC 5 - 给电影表和模型添加新字段

    在本节中,您将使用Entity Framework Code First来实现模型类上的操作。从而使得这些操作和变更,可以应用到数据库中。 默认情况下,就像您在...

    葡萄城控件
  • Laravel展示产品-CRUD之show

      上一篇讲了Laravel创建产品-CRUD之Create and Store,现在我们来做产品展示模块,用到是show,①首先我们先修改controller...

    ytkah
  • selenium-java web自动化测试工具

    本篇文章由来,这两天整理了下自己经常使用而且很熟练的项目,今天突然想起漏了一个,补上了,但想到还没对应的博客,那就写一个简单的

    肖哥哥
  • 你听过 React Fragments吗??

    React 中常见模式是为一个组件返回多个元素。为了包裹多个元素你肯定写过很多的 div 和 span,进行不必要的嵌套,无形中增加了浏览器的渲染压力。

    前端博客 : alili.tech
  • CSS旋转魔方

     想不想做一个3D魔方,把儿子的照片放进去,外面是你,里面是他。本人从业至今,自诩是动画机器人,苦心钻研各种动画,精通CSS3、Canvas等,不管你要做什么,...

    我不是费圆
  • Vue里v-for循环双层数组

    任我行RQ
  • Python爬虫获取豆瓣电影并写入excel

    这篇文章主要介绍了Python爬虫获取豆瓣电影并写入excel ,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友可以参考...

    python学习教程
  • Position定位

    CSS中position属性是比较常用的元素定位方案,position常用的取值有static、relative、absolute、fixed、sticky、i...

    WindrunnerMax

扫码关注云+社区

领取腾讯云代金券