jquery - angularjs sortable - 更新排序顺序属性

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

我正在创建一个 angularjs 应用程序,它也使用 jquery ui 可排序。我正在寻找一种干净的方法,在每次执行排序时根据模型在页面上的位置更新模型上的“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();
                }
            });
        }
    };
});

还有我的“syncOrder”函数:

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

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

谢谢!

最佳答案

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

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

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

app.directive('sortable', function ($timeout) {
  return function (scope, element, attributes) {
    element.sortable({
        stop: function(event, ui){
            scope.syncOrder(element.sortable('toArray'));
        }
    });
  };
});

现在我们可以修改 syncOrder 函数来迭代模型中的所有对象,然后迭代由 sortable 传入的数组中的所有元素,比较 ID,并更新模型以反射(reflect)新职位。

$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;
            }
        });
    });
};

一旦我们完成了设置,我们就需要做最后一件事。来自 jquery 可排序小部件的 stop 事件在 Angular 执行 block 的外部执行。换句话说,Angular 无法准确知道可排序对象是否要更新其 $ 上的 objects 数组。范围。因此,当您排序时,您的 View 似乎不会更新;不过,如果您迭代数组,您会看到数组确实更新了。

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

return function (scope, element, attributes) {
    element.sortable({
        stop: function(event, ui){
            // Without this, angular magic won't happen when the objects array is updated.
            scope.$apply(function () {
                scope.syncOrder(element.sortable('toArray'));
            });
        }
    });
};

Working Demo

关于jquery - angularjs sortable - 更新排序顺序属性,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24816971/

相关文章:

javascript - 提交 AJAX 表单时 jQuery 意外刷新页面

angularjs - ionic : Check Internet Connection using Cordova

javascript - jQuery 上下文选择器差异

jquery - J表: 'An error occured while communicating with the server ' while updating or deleting records

angularjs - 为什么我得到 Lexerr :unterminated quote error?

jquery - 如何优雅地展开 jQuery UI 工具提示?

javascript - 执行顺序行为

jquery - 单击 <a> 标签更改 <li> 的背景图像

javascript - 如何通过图像按钮触发日历弹出?

javascript - 在 AngularJS 中从数组中删除元素时出错