我正在创建一个 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 无法准确知道可排序对象是否要更新其 $ 上的
。因此,当您排序时,您的 View 似乎不会更新;不过,如果您迭代数组,您会看到数组确实更新了。objects
数组。范围
我们需要强制 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/