奇怪的角点击问题 - 过滤器&表

时间:2016-11-24 18:00:17

标签: javascript html angularjs zurb-foundation angularjs-filter

所以我在应用程序的基础上遇到了一个奇怪的问题。 (以下所有代码)

我有一个数据表,其中包含一个过滤器对象(链接到单个范围对象的表单元素的可视化条)(在一个控制器内)。这包括select三个选项,按完成状态过滤表格(全部,完整,不完整);

每行ng-repeat并附加ng-click以突出显示该行(出于可读性目的)。然后,我在每行的最后td处有一个样式复选框,将行标记为"完成"。

当我加载页面并单击"完成"复选框我可以看到我的服务功能更新服务器和本地websql文件。如果我选择一个过滤器复选框(说方向)并单击一个"完成"复选框有效;

当我使用"完成"过滤列表时,它停止工作过滤选择下拉;我可以看到复选框被选中并且范围摘要但是从不调用check函数;任何想法?

CODE:

//CONTROLLER

  .controller('tableShow', function($scope, $state, $http, dataService, $filter) {

  $scope.list = {};
  $scope.data = function() {
    console.log('filter'); //<-- SHOWS IN CONSOLE ON HIGHLIGHT OR CLICK OF COMPLETE REGARDLESS OF FUNCTION BEING CALLED;
    return $filter('filter')(Object.values(dataService.data), $scope.list);
  };

  $scope.headers = ["date", "t_id", "type", "code", "desc", "io"]; // used to only show required headers

  // LIST MANAGEMENT

  $scope.sortedBy = 'date';
  $scope.reversed = true;

  $scope.setSort = function(col) {
    $scope.reversed = ($scope.sortedBy == col ? !$scope.reversed : false);
    $scope.sortedBy = col;
  };

  //MISC FN
  $scope.highlight = function(e) {
    var row = e.target.tagName === 'tr' ? e.target : utils.getClosest(e.target, 'tr'),
      table = utils.getClosest(row, 'tbody'),
      preHl = table.querySelectorAll('tr[highlight]'),
      highlighted = row.hasAttribute('highlight');


    if (preHl.length > 0) {
      for (var i = preHl.length - 1; i >= 0; i--) {
        preHl[i].removeAttribute('highlight');
      }
    }

    if (!highlighted)
      row.setAttribute('highlight', '');
  };


  $scope.unCheck = function(e) {

    console.log(e);
    var input = e.target,
      lastVal = input.parentNode.checked,
      model = input.getAttribute('ng-model').split('.');

    console.log(input.value, input.parentNode.checked);
    if (input.value !== input.parentNode.checked) {
      input.parentNode.checked = input.value;
      return;
    }

    input.checked = false;
    input.parentNode.checked = '';

    if (model.length == 1)
      delete $scope[model[0]];
    else if (model.length == 2)
      delete $scope[model[0]][model[1]];
    else if (model.length == 3)
      delete $scope[model[0]][model[1]][model[2]];
    else
      alert('There was an error matching the data model!');

  };

  $scope.complete = function(e, row) {
    e.preventDefault();
    e.stopPropagation();
    // added the above as thought the click might be bubbling to highlight

    console.log('SUBMITTING', e, row); // does not show if complete is set
    var input = e.target,
      lastVal = input.parentNode.checked,
      newVal = input.value,
      sub = input.checked ? 1 : 0,
      _id = angular.copy(row.id), // thought this may be the problem but didnt help;
      data = {
        update: {
          data: [{
            id: _id,
            completed: sub
          }]
        }
      };

    input.disabled = true;

    sendData(data)
      .then(updated, failed);

    function updated() {

      if (input.value !== input.parentNode.checked) {
        input.parentNode.checked = input.value;
      } else {
        input.checked = false;
        input.parentNode.checked = '';
      }

      row.completed = sub;
      input.disabled = false;
    }

    function failed() {
      if (input.value == input.parentNode.checked) {
        input.parentNode.checked = input.value;
      } else {
        input.checked = false;
        input.parentNode.checked = '';
      }

      input.disabled = false;
    }
  };
});

HTML

<section class="grid-content vertical">
  <form name="Form" class="grid-block vertical" ng-submit="">
    <fieldset name="ListSelect">
      <legend>Filter</legend>
      <div class="grid-block wrap">
        <div class="grid-content small-3">
          <div class="checker grid-block small-up-2">
            <input id="IN" name="io" type="radio" ng-model="list.io" value="IN" ng-click="unCheck($event)">
            <label for="IN" onclick="" class="grid-content noscroll">
              <span class="corners"></span> IN
            </label>
            <input id="OUT" name="io" type="radio" ng-model="list.io" value="OUT" ng-click="unCheck($event)">
            <label for="OUT" onclick="" class="grid-content noscroll">
              <span class="corners"></span> OUT
            </label>
            <span></span>
          </div>
        </div>
        <div class="grid-content small-3">
          <div class="checker grid-block small-up-2">
            <input id="TYPE1" name="type" type="radio" ng-model="list.type" value="type1" ng-click="unCheck($event)">
            <label for="TYPE1" onclick="" class="grid-content noscroll">
              <span class="corners"></span> TYPE1
            </label>
            <input id="TYPE2" name="type" type="radio" ng-model="list.type" value="type2" ng-click="unCheck($event)">
            <label for="TYPE2" onclick="" class="grid-content noscroll">
              <span class="corners"></span> TYPE2
            </label>
            <span></span>
          </div>
        </div>
        <div class="grid-content small-3">
          <select name="complete" ng-model="list.complete">
            <option value="" selected>All</option>
            <option value="1">Completed</option>
            <option value="0">InComplete</option>
          </select>
        </div>
      </div>
    </fieldset>
    <aside class="small-12 grid-block corners large vertical">
      <div class="grid-block data ddLine">
        <div class="grid-content data">
          <table class="responsive" id="inventoryList">
            <thead>
              <th ng-repeat="v in headers" ng-hide="(v == 'type' && list.type) ">
                <label ng-click="setSort(v)">
                  {{v | addSpace}}
                  <i class="fa fa-fw" ng-class="{'fa-sort-down': reversed && v == sortedBy, 'fa-sort-up': !reversed && v == sortedBy, 'fa-sort': v != sortedBy}"></i>
                </label>
              </th>
            </thead>
            <tbody>
              <tr class="anim-4" ng-click="highlight($event);" ng-repeat="r in data() | orderBy:sortedBy:reversed" ng-class="r.disabled == 1 ? 'disabledRow' : ''">
                <td ng-repeat="v in headers" class="nowrap" ng-hide="(v == 'type' && list.type)">
                  {{ v == 'date' ? (r[v] | dateShow) : (r[v] || '-')}}
                </td>
                <td>
                  <div class="checker grid-block small-up-2">
                    <input id="complete-{{r.id}}" type="checkbox" name="complete" ng-model="r.complete" ng-true-value="1" ng-false-value="0" ng-click="completed($event, r);">
                    <label for="complete-{{r.id}}" class="grid-content noscroll">
                      <span class="corners"></span>
                    </label>
                  </div>
                </td>
              </tr>
            </tbody>
          </table>
        </div>
      </div>
    </aside>
  </form>
</section>

注意:

  • 此应用中不存在jQuery
  • 我知道在控制器中添加DOM属性被认为是不好的做法(我向你保证这不是问题,我已经检查过了)
  • 我必须使用Object.values,因为我的数据结构与角度不匹配&#39;对象结构数组; (我自己的错也来不及 改变); <!/ LI>
  • 我已经删除了不相关的代码和类来缩小这个问题的大小;

EDIT 经过一番思考后,我认为这可能是由于过滤列表而导致的。 &#34;完成&#34;的模型与行相关联;简而言之,通过单击完整复选框来更改行的模型会导致列表过滤器在调用函数之前删除该行;虽然我还不确定如何解决这个问题,因为我还在学习角绳

1 个答案:

答案 0 :(得分:0)

正如我所想,这个WAS链接到$scope.data中的过滤器,在点击功能被调用之前在摘要期间被调用。

罪魁祸首是“完整”的复选框,同时附加了ngClick和ngModel。当列表被“完成”过滤并单击复选框时,它会切换触发摘要的行“完成”值,这意味着在调用ngClick之前该行已从列表中过滤掉。

由于隐藏了input[checkbox]并且label中的图形替换了它,我只是将label与删除for attr的复选框分开并移动{ {1}} ngClick本身。现在只有在后端已经更新时才会更新行;