添加select2的Angular指令会破坏模型



我用ng-repeat创建了一个表,并在单击其中一个单元格时添加了一个select2 ddl指令。一切都工作得很漂亮,所选值在模型中更新(所有与select2工作按预期),但不知何故,模型似乎被包含在代码中的这个指令破坏了(无论我是否从ddl中选择了一个项目)。

在表中加载了数据之后,如果我试图从模型中删除一个项目(使用splice):

$scope.Info.splice(index,1);

甚至用原始模型的副本替换整个模型:

$scope.Info = angular.copy($scope.Info2);

我在控制台得到一个错误,说'Array.prototype。forEach'为空或不是对象。到目前为止,我只在IE8(我们支持的浏览器)中看到过这种行为。我在Chrome中没有看到这种情况。

如果我从指令模板的输入中删除'click- edit-select2',我看不到错误,所以我不禁认为这是指令中的问题,甚至更糟的是,在select2脚本中,我不知道如何查明(希望不是这样)。

提前道歉!我开始创建一个plunk,但意识到plunks在IE中不起作用,所以很难看到我所指的错误。

我还应该提到,我们不仅支持IE8,我们也在使用旧版本的脚本:angular.js: 1.2.19select2-min.js: 3.4.8Ui-bootstrap: 0.8.0(和模板)bootstrap.js: 2.3.1bootstrap.css: 2.3.1

请看看代码,让我知道是否有办法消除这个错误:

HTML:

<body ng-app="app" ng-controller="TestController">
<table class="table table-bordered">
        <thead>
          <tr role="row">
            <th tabindex="0" class="sorting" aria-label="" ng-click="predicate = 'Id'; reverse=!reverse">
              ID
            </th>
            <th tabindex="0" class="no_edit sorting" aria-label="">
              Description
            </th>
          </tr>
        </thead>
        <tbody ng-repeat="item in Info">
          <tr>
            <td click-to-edit-select2="item.id">
              {{item.Id}}
            </td>
            <td>
              {{item.Description}}
            </td>
          </tr>
        </tbody>
      </table>
</body>

控制器:

var app = angular.module("app", ["ui.select2", "ui.bootstrap", "click-to-edit-select2"]);
app.controller('TestController', function($scope, $http, $element, $filter, $modal) {
  $scope.Info2 = [{
    "UniqueIndex": "t1",
    "Status": "",
    "Id": "1",
    "Description": "This Description",
  }, {
    "UniqueIndex": "t2",
    "Status": "",
    "Id": "2",
    "Description": "That Description",
  }];
  //This works . . .initializing the table, before the directive is applied
  $scope.Info = angular.copy($scope.Info2); 

  $scope.DeleteRow = function(item) {
        //Either one of these statements throws the error in the console, 
        //and the model is not updated in the view
        $scope.Info = angular.copy($scope.Info2);
        $scope.Info.splice(0, 1);
    }
})

指令:

angular.module('click-to-edit-select2', [])
  .directive("clickToEditSelect2", function() {
      var editorTemplate = '<td class="click-to-edit-select2">' +
      '<div style="height:20px" ng-click="enableEditor()" ng-hide="view.editorEnabled">' +
      '{{value}} ' +
      '</div>' +
      '<div ng-show="view.editorEnabled" ng-click="save()">' +
      '<input type="hidden" ui-select2="select2Options" ng-model="view.editableValue" ng-change="changeText()" />' +
      '</div>' +
      '</td>';
      return {
          restrict: "A",
          replace: true,
          template: editorTemplate,
          scope: {
              value: "=clickToEditSelect2"
          },
          controller: function($scope, $element, $attrs) { 
              $scope.view = {
                  editorEnabled: false
              };
              $scope.enableEditor = function() {
                      $scope.view.editorEnabled = true;
                      $scope.view.editableValue = $scope.value;
              };
              $scope.disableEditor = function() {
                  $scope.view.editorEnabled = false;
              };
              $scope.save = function() {
                  $scope.value = $scope.view.editableValue.id;
                  $scope.disableEditor();
              };

              var initSelectionCb = function(item, callback) {
                  if (item != "") {
                      var id = item.val();
                      var data = { id: id, text: id };
                      callback(data);
                  }
              };
              $scope.select2Options = { 
                  placeholder: "Select",
                  multiple: false,
                  width: "resolve",
                  initSelection: function(item, callback) {
                      //selects the initial item
                      initSelectionCb.call(self, item, callback);
                  },
                  ajax: {
                      url: "/GetDropDownListForSelect2",
                      type: "POST",
                      contentType: "application/json",
                      data: function(term, page) {
                          var Json = {};
                          Json.term = term;
                          Json.page = page;
                          return Json;
                      },
                      results: function(data, page) {
                          return { results: data.options };
                      }
                  }
              }

          }
      };
  });

嘘!我能在这里找到答案

我把下面的代码放在我的脚本文件的顶部,错误消失了,拼接和复制方法现在在IE8中工作:

if (!('forEach' in Array.prototype)) {
    Array.prototype.forEach = function(action, that /*opt*/) {
        for (var i = 0, n = this.length; i < n; i++)
            if (i in this)
            action.call(that, this[i], i, this);
    };
}

看看IE8的Angular指南,它并不完全支持。也就是说,有一种方法可以解决这个问题那就是修改

<body ng-app="app" ng-controller="TestController">

<body ng-app="app" id="ng-app" ng-controller="TestController">

,并将angular命名空间添加到页面的顶部。

<html xmlns:ng="http://angularjs.org">

你可以在这里查。

编辑:为了将来参考,codennewbie有下面Array.prototype.Foreach问题的解决方案。如果你有这个问题,一定要阅读

相关内容

  • 没有找到相关文章

最新更新