AngularJs - <ul> <li>元素在选中其复选框时位于顶部

时间:2016-12-01 11:48:56

标签: javascript angularjs

此问题基于this previous one

我有ng-repeat这样:

<li ng-repeat="opt in namesCtrl.uniqueCars">
    <input type="checkbox" ng-model="namesCtrl.filter['cars'][opt.element]" | orderBy:['checkbox','-count']"><p2>{{opt.element}} ({{opt.count}})</p2>
</li>

元素来自this.uniqueCars

this.uniqueCars=[
    {'element':'Ford','count':3,'checkbox':false},
    {'element':'Honda','count':2,'checkbox':false},
    {'element':'Ferrari','count':1,'checkbox':false},
    {'element':'Delorean','count':6,'checkbox':false}
];

视图中的选中项目转到this.filter(我用于其他目的)

this.filter = {
    "cars": {}
}

所以我想要实现的是在视图中订购复选框列表,因此当选中其中一个项目时,它会转到顶部,类似这样

enter image description here

enter image description here

为了做到这一点,我有一个$watch就像这样

$scope.$watch("namesCtrl.filter", function(nv,ov){
    angular.forEach(self.uniqueCars, function(opt){
    opt.checkbox = nv.cars[opt.element]
    })
}, true)

但是当按复选框值排序时行为非常不一致(当第一次点击它完成作业时,OK,但是当取消它时不起作用,再次点击它时会以相反的方式对其进行排序)。

所以我想通过修改$watch来做到这一点。 (我这样做是因为IRL this.filter可以被其他元素修改,所以我需要观察那里的变化。)

PS:this.uniqueCars.checkbox字段是我插入的,只是为了使排序成为可能,所以修改它是安全的。

您可以查看工作Plunker here

2 个答案:

答案 0 :(得分:2)

你几乎做对了。
您的$watch功能存在一个小问题:如果汽车尚未成为namesCtrl.filter的成员,则其checkbox值将从namesCtrl.uniqueCars中移除,因为它未定义。
如果你这样处理这个案子:

$scope.$watch("namesCtrl.filter", function(nv,ov){
  angular.forEach(self.uniqueCars, function(opt){
    var value = nv.cars[opt.element] ? nv.cars[opt.element].checkbox : false;
    opt.checkbox = value;
  });
}, true);

然后你的订购很好。除了您还需要按相反顺序的复选框订购:

<li ng-repeat="opt in namesCtrl.uniqueCars | orderBy:['-checkbox','-count']">

请参阅working plunker

答案 1 :(得分:1)

为什么你不能修改checkbox自己呢?将输入的模型更改为opt.checkbox并注释注意使一切正常。我认为这样做会更好。

但您可以将opt.checkbox = nv.cars[opt.element]修改为opt.checkbox = !!nv.cars[opt.element]以使其正常工作(cars对象中的复选框属性为undefined,这会破坏正确的排序。)