当contenteditable Elements使用Angular.js更改时,更新$scope

Update $scope when contenteditable Elements Change with Angular.js

本文关键字:更新 scope Elements contenteditable 使用 Angular js      更新时间:2023-09-26

我是Angular.js的新手,已经尝试过学习如何在ng-repeat中双向绑定contenteditable元素。

我正在使用控制器之间的共享"存储",例如

  pushupsApp.factory('grids', function () {
    return [
      ...
      {
        'id': 1409875200000, // 2014-09-05
        'sets': [
          5,
          10,
          15,
          20,
          25,
          30
        ]
      },
      {
        'id': 1409912060233, // 2014-09-05 11:14
        'sets': [
          5,
          10,
          15,
          20,
          25,
          30
        ]
      }
    ];
  });
  pushupsApp.controller('indexController', function ($scope, grids) {
    $scope.grids = grids;
  });

这似乎很有效;如果我在一个控制器中更改$scope.grids,那么在刷新页面之前,这种更改在所有其他控制器中都是持久的。

根据本教程和Angular.js文档中的示例,我有以下控制器和指令:

  pushupsApp.controller('gridController',
    function ($scope, $routeParams, $filter, grids) {
      var now = new Date(Date.now());
      $scope.date = $filter('date')(now, 'yyyy-MM-dd');
      $scope.grids = $filter('filter')(grids, {'id':$scope.date},
        function (actual, expected) {
          return angular.equals($filter('date')(actual, 'yyyy-MM-dd'),
            $filter('date')(expected, 'yyyy-MM-dd'));
        });
  }).directive('contenteditable', function () {
    return {
      restrict: 'A',
      require: 'ngModel',
      link: function (scope, element, attributes, ngModel) {
        ngModel.$render = function () {
          element.html(ngModel.$viewValue || '');
        };
        element.bind('keyup', function () {
          scope.$apply(function () {
            ngModel.$setViewValue(element.html);
          });
        });
        }
      };
    });

问题

我的意图是,当我编辑ng-repeat中的contenteditable元素时,$scope.grids也会在keyup事件触发时更新,以镜像编辑。

$scope.grids没有更新。我试着研究自己可能发生的事情,但由于我是Angular.js的新手,我真的不知道我应该寻找什么!我所发现的一切都表明我当前的代码应该可以工作。

为了完整起见,我也有以下模板:

<script type="text/ng-template" id="grid.html">
  <p>{{date}}</p>
  <ul>
    <li ng-repeat="grid in grids">
      <p ng-if="grids.length > 1">{{grid.id | date:'shortTime'}}</p>
      <ul>
        <li contenteditable="" ng-model="grids" ng-repeat="set in grid.sets">
          {{set}}
        </li>
      </ul>
    </li>
  </ul>
</script>

最终,我的"商店"将是持久的,但现在我很高兴它只在每次会话中。

对于我的Angular.js代码以及可能存在的问题,我们将非常感谢您的任何帮助,以及任何其他建议!

谢谢你的帮助!Jon

这可能有帮助

我注意到,当我将模板中的ng-model属性更改为grid.sets时,当keyup事件触发$scope.grids更新时但是,整个集合列表将从DOM和$scope.grids中删除。这里可能正在发生一些事情,这可能有助于解决问题;希望来了!

在我发现之后(请参阅这可能有帮助),我突然非常接近解决方案!

由于从$scope.grids中删除了整个数据块,我现在知道我可以将该块缩小到contenteditable元素和"存储"中相应的数据块。

ng-template属性更改为grid.sets[$index]就是这样做的。

事实证明,元素被从DOM中删除是因为我在这里缺少括号:

          scope.$apply(function () {
            // ngModel.$setViewValue(element.html);
            ngModel.$setViewValue(element.html());
          });

那只是粗心大意。contenteditable元素在每次往返之后都会丢失focus,所以我将事件改为在blur上激发。

问题,已解决:-)

我希望这有帮助,Jon