模型绑定到本地范围。更改和初始化操作真实模型

Model binding to local scope. Change and init manipulate real model

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

我最终绑定到一个 fake/local 范围变量,然后在 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>

简而言之 - 我不能将模型绑定到复选框的原因是因为它反映了此人的密钥是否在日期对象的数组中 NOT。我的 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 };
};

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

我正在尝试找出最佳方法,但无法下定决心。我有一个有效的解决方案来触发网格的完全重建(请注意,这个 ng-repeat 只适用于一个人 - 我有一个日期列表,用于一个人列表 = 大网格),如下所示:

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

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

我正在考虑的另一个解决方案是检查事件数据以确定更改的日期,然后找到该日期的所有复选框(每个人一个)并手动触发更改事件(可能使用 jqlite内置 angular 到 element)。然而,这个解决方案让我尖叫 'wrong',因为这些 dom 操作违背了 angular.

的声明性

你们认为最好的是什么?

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

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

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

我将 question/answers 打开一段时间,看看是否有人能想出更好的解决方案。

不要介意 'new' _dates 变量 - 我做了一些重构并将其移动到服务中。