AngularJS:在使用嵌套的JQuery Sortables时保持Dom和Model同步

时间:2012-08-16 23:37:16

标签: javascript angularjs

在使用嵌套的JQuery sortables时,如何使DOM和模型保持同步?假设我有一个控制器,其定义如下:

function testCtrl($scope) {
    $scope.data = [{'name' : 'Test 1',
                   'index' : 0,
                   'values': [{'name' : 'sub test 1-1', 'index' : 0}, {'name' : 'sub test 1-2', 'index' : 1}]},
                   {'name' : 'Test 2',
                   'index' : 1,
                   'values': [{'name' : 'sub test 2-1', 'index' : 0}, {'name' : 'sub test 2-2', 'index' : 1}]}
   ];

   $scope.orderProp = 'index';
}

现在我想使用以下模板在JQuery sortables中显示第一级数据和第二级数据:

<ul ng-sortable='data'>
    <li ng-repeat="d in data | orderBy:orderProp">
        <p>{{d.name}}</p>
        <ul ng-Sub-Sortable="d.values">
            <li ng-repeat="sub in d.values">{{sub.eg}}</li> 
        </ul>
    </li>
</ul>

我使用指令来指定两种不同类型的可排序列表,因为它们的行为不同(为简洁起见,从下面删除):

app.directive("ngSortable", function(){
    return {
        link: function(scope, element, attrs){                  
            element.sortable();
        }
    };
}

app.directive("ngSubSortable", function(){
    return {
        link: function(scope, element, attrs){                  
            element.sortable();
        }
    };
}

现在,当用户对列表进行排序时,如何更新模型以确保索引正确,以便将来正确输出列表?

2 个答案:

答案 0 :(得分:1)

您最好使用ngModel与dom同步数据

你可以尝试这个: https://github.com/JimLiu/Angular-NestedSortable

答案 1 :(得分:0)

我发现保持模型与嵌套排序中具有位置相关数据的项目的DOM同步的最佳方法是将当前位置作为属性添加到每个元素,如下所示:

<ul ng-sortable='data'>
    <li ng-sortable-index="{{$index}}" ng-repeat="d in data | orderBy:orderProp">
        <p>{{d.name}}</p>
        <ul ng-Sub-Sortable="d.values">
            <li ng-sortable-index="{{$index}}" ng-repeat="sub in d.values">{{sub.eg}}</li> 
        </ul>
    </li>

然后在初始化jQuery sortable的指令中,可以按如下方式指定可排序更新方法:

element.sortable({
    update: function(event, ui) {
        var model = scope.$eval(attrs.ngSubSortable);

        // loop through items in new order
        element.children().each(function(index) {
            // get old item index
            var oldIndex = parseInt($(this).attr("ng-sortable-index"), 10);
            model[oldIndex].index = index;
         });

         scope.$apply();
     }
});