Angular 1:最后一个复选框没有'刷新页面后不要保持选中状态

Angular 1: Last checkbox doesn't stay checked after page refresh

本文关键字:状态 刷新 复选框 最后一个 Angular      更新时间:2023-10-26

我正在将所有数据保存到localStorage中。选中复选框时,将调用函数来更改项目状态。它运行良好。但是,在页面刷新后,最后一个选中的项目将被取消选中(或者如果它被取消选中,它将被选中),而其他项目则工作正常。为什么刷新页面后会忽略最后一个操作?

这是代码笔:http://codepen.io/kunokdev/pen/vGeEoY?editors=1010

(添加一些项目,点击"点击我",然后刷新页面,最后一个操作将被忽略)

视图:

<div ng-app="TaskApp" ng-controller="ToDoCtrl">
  <form>
    <input type="text" ng-model="toDoItem">
    <input type="submit" ng-click="addToDoItem()">
  </form>
  <div>
    <ul>
      <div
        ng-repeat="item in toDoItems |
                   orderBy: 'createdAt'
                   track by item.createdAt">
        <b>Content:</b> {{item.content}} <br>
        <b>Completed?</b> {{item.completed}}
        <md-checkbox ng-model="item.completed" ng-click="toggleToDoItem(item.completed)" aria-label="todo-checkbox">
          CLICK ME
        </md-checkbox>
      </div>
    </ul>
  </div>
</div>

和JS:

var ls = {};
ls.get = function(key) {
    return JSON.parse(localStorage.getItem(key));
};
// sets or updates a value for a key
ls.set = function(key, val) {
    localStorage.setItem(key, JSON.stringify(val));
};
// returns true if value is set, else false
ls.isSet = function(key) {
    var val = ls.get(key);
    return ( null === val || 'undefined' === typeof val) ? false : true;
};
// removes a set item
ls.remove = function(key) {
    localStorage.removeItem(key)
};

var TaskApp = angular.module('TaskApp', [
  'ngMaterial',
  'taskAppControllers'
]);
var taskAppControllers = angular.module('taskAppControllers',[]);
taskAppControllers.controller('ToDoCtrl', ['$scope',
  function($scope){
    //
    loadToDoItems = function(){
      var data = ls.get("toDoData");
      if (data == null) data = [];
      return data;
    };
    //
    $scope.toDoItems = loadToDoItems();
    //
    $scope.addToDoItem = function(){
      var toDoItems = $scope.toDoItems;
      var newToDoItem = {
        "content" : $scope.toDoItem,
        "createdAt" : Date.now(),
        "completed" : false
      }
      toDoItems.push(newToDoItem);
      ls.set("toDoData", toDoItems);
      $scope.toDoItem = "";
    };
    //
    $scope.toggleToDoItem = function(item){
      console.log('test');
      var toDoItems = $scope.toDoItems;
      for (var i = 0; i < toDoItems.length; i++)
        if (toDoItems[i].createdAt === item){
          if (toDoItems[i].completed == true)
            toDoItems[i].completed = false;
          else
            toDoItems[i].completed = true;
        }
      ls.set('toDoData', toDoItems);
    };
    //
}]);

md-checkbox被设计为切换您在ng-model中放入的任何内容,因此在您的代码中,md-checkbox切换completed属性,然后在$scope.toggleToDoItem函数中再次将其更改回。为什么这适用于除了上次点击之外的所有项目,我不确定。

因此,我将ng-click更改为仅将项目保存到本地存储,但仍然遇到相同的问题,这使我相信问题是由在md-checkbox上使用ng-click引起的。

 <md-checkbox ng-model="item.completed" ng-click="saveToLocalStorage()" aria-label="todo-checkbox">
    CLICK ME
 </md-checkbox>
$scope.saveToLocalStorage = function() {
  ls.set('toDoData', $scope.toDoItems);
};

所以我取下了ng-click,在$scope.toDoItems上安装了一块手表。

<md-checkbox ng-model="item.completed" aria-label="todo-checkbox">
$scope.$watch("toDoItems", function() {
  ls.set("toDoData", $scope.toDoItems);
}, true);

Codepen

--编辑--

只要阅读文档,就会觉得自己像个白痴,应该使用ng-change而不是ng-click。来自有关ng-change:的文档

当输入由于用户与输入元素的交互而发生更改时要执行的角度表达式。

也就是说,上面关于不需要自己切换completed属性的内容仍然有效。

您正在将item.completed(在HTML中)传递给toggleToDoItem(item)方法。在数组循环中,然后比较项目。item.comcompleted参数的已创建字段。这是将Date类型与Bool进行比较。这是怎么回事?