0

我真的很想将我的复选框绑定到我的模型,但我还没有找到这样做的好方法,因为我在模型中有自定义逻辑。

我最终绑定到一个假/本地范围变量,然后在 ng-change 上更新模型。我使用 ng-init 设置复选框的初始值,如下所示:

<td ng-repeat="date in dates">
<md-checkbox ng-model="cb.state" aria-label="{{date.txt}}"
ng-change="saveState(person, date, cb.state)" 
ng-init="cb = getState(person, date);" ></md-checkbox>{{date.persons.length }}
</td>

简而言之 - 我不能只将模型绑定到复选框的原因是因为它反映了此人的密钥是否不在日期对象的数组中。我的getState和saveState如下:

$scope.saveState = function(person, date, state) {
    var index = date.persons.indexOf(person.name);

    if (state && index >= 0) {
        date.persons.splice(index, 1);
    } else if (!state && index < 0) {
        date.persons.push(person.name);
    }

    dates.$save(date);
};

$scope.getState = function(person, date) {
    return { state : date.persons.indexOf(person.name) < 0 };
};

这确实有效,这很棒。当另一个客户更新模型时,问题就来了。当我的模型改变时,视图也会改变。我实际上得到了 people 数组的更新后的新长度(这就是我将它放在示例中的原因) -{{ date.persons.length }}已更新。另一方面,我的复选框没有更新 - 这很明显,因为 ng-init 不会再次被调用(它只会在第一次初始化时被调用)并且我的 ng-change 也没有被调用 - 它仅在复选框时调用本身已更改/单击。

我试图找出最好的方法是什么,但无法下定决心。我有一个可行的解决方案来触发网格的完全重建(请注意,这ng-repeat仅适用于一个人 - 我有一个人员列表的日期列表 = 大网格),如下所示:

dates.$watch(function (eventData) {
  dates = $scope.dates = $firebaseArray(fb.child("dates"));
});

由于要更新所有数据,它会闪烁屏幕 - 我还担心如果一个客户端上的用户在此事件到达以更新整个事物时更新网格会发生什么。

我正在考虑的另一个解决方案将检查 eventData 以确定更改的日期,然后找到该日期的所有复选框(每个人一个)并手动触发更改事件(可能使用jqlite内置的 angular through element)。然而,这个解决方案对我来说是“错误的”,因为这些 dom 操作违背了 angular 的声明性。

大家觉得最好是什么?

4

1 回答 1

0

我最终得到了一个解决方案来观察变化,但只更新受影响的日期。这仍然会更新列表中的所有人员,但至少它只更新一个日期。

_dates.$watch(function (eventData) {
  var record = _dates.$getRecord(eventData.key)
  if (!record)
    return;

  var index = _dates.indexOf(record);
  _dates[index] = angular.copy(record);
});

我会暂时保留问题/答案,看看是否有人能提出更好的解决方案。

不要介意“新”_dates 变量——我做了一些重构并将其移至服务中。

于 2015-03-16T09:41:03.637 回答