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关联了起来,同时发生改变。

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

 

posted @ 2014-12-07 22:22  风之约  阅读(245)  评论(0编辑  收藏  举报