【问题标题】:How do I create closures for model getter-setter in angular?如何以角度为模型 getter-setter 创建闭包?
【发布时间】:2015-02-03 20:57:32
【问题描述】:

我有一些使用 Angular 的 ng-repeat 渲染的数据。我想允许用户通过选中每个元素前面的复选框来选择视图中的元素。最简单的方法是为模型中的每个元素添加一个“选定”属性。但是,我更愿意更精细地分离关注点,而不是用 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 传递给角度视图?

【问题讨论】:

    标签: javascript angularjs


    【解决方案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. 使用此方法,访问器函数会不断重新创建。这可能会影响性能(速度和内存使用),至少在真实页面上是这样。要对其进行可视化,请在createSelectionGetterSetter 函数的开头添加console.log('Creating accessor')

    2. 您需要额外处理data 列表更改的情况,尽管您现在可以轻松地为selection 指定初始值。

    【讨论】:

    • 感谢您的想法。我使用了第二种方法的变体,对创建的 getter/setter 进行了记忆 - 请参阅 jsfiddle.net/afxuaf3m
    • 是的,如果您想使用 getterSetter 选项,我认为这就是您要走的路。
    猜你喜欢
    • 1970-01-01
    • 2014-08-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-10-29
    • 2011-02-23
    • 1970-01-01
    相关资源
    最近更新 更多