首页 > 代码库 > UEGrids.js

UEGrids.js

最近项目需要,接触了一下angularjs, 感觉双向绑定非常的强大,于是花几个小时的时间,把项目里要实现的一个类似表格数据交换的功能写了一下,angular支持module封装,上手后使用感觉思维也很清晰。于是贴一下主要代码:

首先是页面

<uegrids grids="gridsLeft" selected="selected" width="200"></uegrids>

这个是自定义的uegrids指令,在controller里面我定议了一个数组对象$scope.gridsLeft, 一个变量$scope.selected,和一个元素属性 width = 200;

$scope.gridsLeft = [                    { id: "10010", with: "red", value: 0.2000 },                    { id: "10010", with: "red", value: 0.2010 },                    { id: "10010", with: "red", value: 0.2013 },                    { id: "10010", with: "red", value: 0.2014 },                    { id: "10010", with: "red", value: 0.2002 },                    { id: "10010", with: "red", value: 0.2012 },                    { id: "10010", with: "red", value: 0.2020 },                    { id: "10010", with: "red", value: 0.2030 },                    { id: "10010", with: "red", value: 0.2003 },                    { id: "10010", with: "red", value: 0.2013 },                    { id: "10010", with: "red", value: 0.2025 },                    { id: "10010", with: "red", value: 0.2034 },                    { id: "10010", with: "red", value: 0.2005 },                    { id: "10010", with: "red", value: 0.2015 },                    { id: "10010", with: "red", value: 0.2026 },                    { id: "10010", with: "red", value: 0.2038 }            ];

        $scope.selected = false;
        $scope.$watch("selected", function(bool) {
          console.log(bool);
        });

 

我使用的是编辑器webstrom 8,代码自动提示完成包含了requirejs、angularjs,真的很方便

然后看下指令部分:

angular.module(‘directives‘, []).        factory("setPos", function() {            return function(width, rows) {                console.time("setPos");                var posArr = [],                    liW = width/ 4,                    liH = 25,                    row = 0,                    col = 1;                for (var row = 0; row < rows; row++) {                    for (var col = 1; col <= 4; col++) {                        posArr.push({left:col*liW, top:row*liH});                    }                }                console.timeEnd("setPos");                return posArr;            }        }).        directive(‘uegrids‘, function() {            return {                restrict: "E",                scope: {                    grids: "=",                    selected: "="                },                templateUrl: "template/uegrids.html",                controller: function($scope, $element, setPos) {                    // console.info($scope.grids, $element);                    // this.grids = $scope.grids;                    var width = $element.attr("width") || 200,                        rows = $scope.grids.length/ 4,                        selectedId = null;                    $scope.setGrid = function(grid) {                        return grid.with ? grid.with : "gray";                    };                    $scope.selectGrid = function(event) {                        if (event.toElement.tagName.toUpperCase() == "LI") {                            $(event.toElement).parent().find("li").removeClass("active");                            $(event.toElement).addClass("active");                            var curId = Number(event.toElement.dataset.id), temp;                            if (curId != selectedId && selectedId !== null) {                                $scope.selected = true;                                // 交换数据                                temp = $scope.grids[selectedId];                                $scope.grids[selectedId] = $scope.grids[curId];                                $scope.grids[curId] = temp;                                console.log("交互后,索引是", selectedId);                                $(event.toElement).removeClass("active");                                selectedId = null;                            } else {                                // $scope.selected = false;                                selectedId = curId;                            }                        }                        event.preventDefault();                        return false;                    };                    var gridPos = setPos(width, rows);                    $scope.setPosition = function(index) {                        var pos = gridPos[index];                        return "left: "+pos.left+"px; top: "+pos.top+"px";                    };                },                link: function(scope, element, attribute, ctrl) {                    /*console.log(scope.grids, element, attribute);*/                    var lis = element.find("li");                },                replace: true            }        })

这里代码有点罗嗦,反正也是第一次写指令,将就一下。然后就是我在requirejs引用了jquery, angualrjs自身有个qlite的dom操作模块,如果检测到引入了jquery,就会优先使用了jquery,我在指令里使用了dom操作。可能这不太符合angualrjs的提倡,但这里只是一个主要思路,并不是一个完整的项目,所以就不按use strict方式来了。

另外发现,在angularjs指令里做循环或计算操作,会使性能下降很快,比如:

<div class="uegrids" ng-click="selectGrid($event)">    <ul>        <li ng-class="setGrid(grid)" style="{{setPosition($index)}}" data-id="{{$index}}" ng-repeat="grid in grids">{{grid.value}}</li>    </ul></div>

假如我在li里加一个ng-style="setPosition($index, grid)", 然后我在setPosition里面去获取$index, grid,然后一堆的计算位置,不好意思,在directive的controller或link里,可能会抛异常。比较好的做法是在controller里预先计算好位置,存到一个变量里面,这里setPosition($index), 只返回变量的引用值即可,效率很高。

数据的交互同于angular的双向绑定,让开发者减少了很多dom的操作,只需要通过简单的ng-click, ng-bind就可以在controller改变数据的同时,迅速地反映在页面上, 而且更妙的是使用scope: {a: "="},使得指令里的a和业务层controller里的a关联了起来,同时发生改变。

然后我在业务层提交的数据,也是指令层交换后的数据,一点也不需要额外做数据修改的处理。

 

UEGrids.js