angularjs sortable - 更新排序顺序属性

时间:2014-07-18 03:54:08

标签: jquery angularjs jquery-ui jquery-ui-sortable

我正在创建一个angularjs应用程序,它也使用jquery ui sortable。我正在寻找一种干净的方式来更新" SortOrder"我的模型上的属性基于它们在页面上的位置,每次执行排序。

这是我到目前为止所拥有的:

<div class="object-container" sortable>
    <div ng-repeat="object in objects">
        <div class="obj-title">{{object.Title}}</div>
    </div>
</div>

这是我的可排序指令:

myApp.directive('sortable', function(){
    return {
        restrict : 'A',
        link : function(scope, element, attributes){
            element.sortable({
                helper : 'clone',
                stop : function(event, ui){
                    scope.syncOrder();
                }
            });
        }
    };
});

我的&#34; syncOrder&#34;功能:

$scope.syncOrder = function(){
    // some speculation here:
    for(var i in $scope.objects){
        $scope.objects[i].SortOrder = ???;
    }
};

SortOrder属性存在并在页面加载时设置,但显然它们需要在排序时更新,因此我可以将更新的集合传递回服务器并保存。有什么想法吗?

谢谢!

1 个答案:

答案 0 :(得分:6)

首先,我们需要一种方法将元素绑定到模型中的对象。我们可以通过在转发器中为我们的元素提供ID并在排序停止时获取该ID来实现此目的。

<ul sortable>
    <li id="elem-{{obj.id}}" ng-repeat="obj in objects">
        { obj.message }}
    </li>
</ul>

现在,在我们的指令中,我们需要使用可排序的toArray方法(documentation here)来获取所有元素ID及其位置的列表,我们需要将其传递给我们的{ {1}}功能。

syncOrder

现在我们可以修改我们的app.directive('sortable', function ($timeout) { return function (scope, element, attributes) { element.sortable({ stop: function(event, ui){ scope.syncOrder(element.sortable('toArray')); } }); }; }); 函数来遍历模型中的所有对象,然后迭代通过sortable传入的数组中的所有元素,比较ID,并更新模型以反映新的位置。

syncOrder

一旦我们完成了这个设置,我们需要做的最后一件事。来自jquery可排序窗口小部件的$scope.syncOrder = function (elemPositions) { // loop over our model objects $scope.objects.forEach(function (obj) { // loop over all the element positions elemPositions.forEach(function (elemId, index) { // shave off the string part of the ID on the element. var id = parseInt(elemId.replace(/elem-/, '')); // Items in the elemPositions array are in the order that they // are on the page. If the element ID matches the ID we gave to // our object, update the sort order to match the current index. if (id === obj.id) { obj.sortOrder = index; } }); }); }; 事件在角度执行块的外部执行。换句话说,当 可排序将更新我们stop上的objects数组时,angular无法确切地知道 if 。因此,您的视图在排序时似乎不会更新;虽然如果你遍历你的数组,你会看到数组确实更新了。

我们需要强制角度来意识到变化即将发生在范围内的对象上。为此,我们将在我们的指令中调用$scope

scope.$apply

Working Demo