如何为角度模型getter-setter创建闭包?

时间:2015-02-03 11:53:24

标签: javascript angularjs

我有一些使用angular的ng-repeat渲染的数据。我想允许用户通过选中每个元素前面的复选框来选择视图中的元素。最简单的方法是向模型中的每个元素添加“selected”属性。但是,我更愿意更细致地分离问题,而不是用UI的状态污染数据模型。此外,我将数据发送回服务器,我宁愿在此之前不必对其进行消毒。所以IMO最好有一个单独的选择模型。基本上我正在尝试做这样的事情:

控制器:

$scope.data = [
    {'name': 'a', 'value': '1'},
    {'name': 'b', 'value': '2'},
    {'name': 'c', 'value': '3'}
];
$scope.selection = {'a': false, 'b': false, 'c': false};

$scope.createSelectionGetterSetter = function(name) {
    return function(newValue) {
        if (angular.isDefined(newValue)) {
            selection[name] = newValue;
        }
        return selection[name];
    }
};

查看:

<div ng-repeat='row in data'>
   <input type='checkbox' ng-model='createSelectionGetterSetter(row.name)' ng-model-options='{ getterSetter: true }' />
   <input type='text' ng-model='row.value' />
</div>

这里的想法是让createSelectionGetterSetter创建一个闭包,将选择状态映射到选择模型中的正确元素。当然它不起作用,因为Angular期望ng-model中有一个实际的getter / setter函数。

如何创建这样的闭包并将它们作为getter / setter传递给角度视图?

1 个答案:

答案 0 :(得分:1)

使用$watchCollection定义selection变量可以轻松完成您想要的内容:

$scope.$watchCollection('data', function(newval) {
    $scope.selection = {};
    if( newval ) {
        angular.forEach(newval, function(val) {
            $scope.selection[val.name] = false;
        });
    }
});

并将其用作:

<input type='checkbox' ng-model='selection[row.name]' />

请参阅小提琴:http://jsfiddle.net/54u0vztr/

捕获:如果您想为selection指定初始值,或者希望在data更改时保留其值,则需要进行一些调整。我相信这些或多或少都是无足轻重的。


如果您想使用getterSetter功能,只需在代码中添加 $scope. selection[name]即可!

小提琴:http://jsfiddle.net/qc5qtg5q/

捕获:

  1. 使用此方法可以不断重新创建访问器功能。这可能会影响性能(速度和内存使用),至少在实际页面上。要将其可视化,请在console.log('Creating accessor')函数的开头添加createSelectionGetterSetter

  2. data列表发生变化时,您需要对案例进行额外处理,尽管您现在可以轻松指定selection的初始值。