0

私はアプリの基礎の角度に奇妙な問題が発生しています。 (下のすべてのコード)奇妙な角度のクリックの問題 - フィルタリング&テーブルのネストされたクリック

私は、1つのページ内の(すべてのコントローラ内の)フィルタオブジェクト(単一のスコープオブジェクトにリンクされたフォーム要素のビジュアルバー)を持つデータテーブルを持っています。これには、完了ステータス(すべて、完全、不完全)でテーブルをフィルタリングする3つのオプションのselectが含まれます。

各行はng-repeatであり、行をハイライト表示するために添付されています(読みやすくするため)。私は最後に各行のtdに "完了"と印を付けるためのスタイル付きチェックボックスを持っています。

ページを読み込んで「完了」チェックボックスをクリックすると、私のサービス機能がサーバーとローカルwebsqlファイルを更新しているのがわかります。私はフィルタのチェックボックス(方向を言う)を選択し、 "完全な"チェックボックスをクリックした場合、それは動作します。

「完全な」フィルタ選択ドロップダウンリストを使用してリストをフィルタリングすると機能しなくなります。チェックボックスがチェックされ、スコープがダイジェストされるが、チェック機能は呼び出されないことがわかります。何か案は?

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> 

NOTES:

  • 何jQueryのは、このアプリでは存在しない
  • コントローラのDOM属性を追加することは悪い習慣とみなされます(これは問題ではないことを私は確信しています)
  • Object.values私のデータ構造は角度構造体の配列と一致しません; (自分の過ちは遅すぎて に変更!);
  • 私は、この質問のサイズを縮小するために、無関係なコードとクラスを削除しました。

EDIT いくつかの考えた後、私は、これは行にリンクされている「完全」のためにリスト&のフィルタリングモデルによって引き起こされるかもしれないと思います。短いチェックボックスをクリックして行のモデルを変更すると、関数が呼び出される前にリストフィルタがその行を削除します。私は今でも角のあるロープを学んでいるので、私はこれを回避する方法はわかりませんが、

+3

http://stackoverflow.com/help/mcve –

+0

私の目は刺す。あなたのコードはAngularのベストプラクティスから数百マイル離れています...私はそれを消化することはできません! – Vi100

+0

建設的な批評は、一般的な「よくあることは間違っている」または「リンクがあります! @ Vi100あなたはjsやhtmlを参照していますか? –

答えて

0

私は思ったとおり、これは、クリック機能が呼び出される前にダイジェスト中に呼び出される$scope.dataのフィルタにリンクされました。

原因は、ngClickとngModelが同時にアタッチされている「完了」のチェックボックスです。リストが "complete"でフィルタリングされ、チェックボックスがクリックされると、ngClickが呼び出される前に行がリストから除外されたことを意味するダイジェストをトリガする行 "complete"値をトグルしました。

input[checkbox]が非表示とlabel内グラフィカル一つは、それを交換したように、私は単にfor ATTRを除去するチェックボックスからlabelを取り外し、label自体にngClickを移動。現在、行はバックエンドが更新されたときにのみ更新されます。