0

私は3つのdropdown箱を持っています。データをフィルタリングする必要があり、チェックボックスの選択に基づいてテーブルに表示する必要があります(single checkboxまたはtwo checkboxesまたはthree checkboxes)。

私は次のことを行いましたが、はっきりと観察すると、 を使用してデータを適切にフィルタリングすることができませんAngularJS

お気に入り:

a. それは動作するはずですindividual checkbox selection:つまり、またはまたはsingle checkboxからいずれかを選択すると、それぞれの一致するフィルター処理されたデータがテーブルに表示されます。 'データを表示しない)NameDescriptionField4

b. 動作するはずですmultiple(two) checkbox selection:つまり、 and と and のような複数のチェックボックスを選択するone from Nameone from Description or one from Descriptionone from Field4 or one from Field4それぞれone from Nameの一致するフィルター処理されたデータがテーブルに表示されます。それ以外の場合、データは表示されません(つまり、チェックボックスの選択と一致しない場合)データが表示されないことを意味します)

c. 動作するはずです:ととmultiple(three) checkbox selectionのような 3 つのチェックボックスを選択すると、それぞれ一致するフィルター処理されたデータがテーブルに表示され、それ以外の場合はデータが表示されません (つまり、チェックボックスの選択と一致しない場合は、データは表示されません)one from Nameone from Descriptionone from Field4

最初のcheckbox選択のみで正常に動作しています。つまり、上記のコード/アプリをロードした後 check、上記の選択のいずれか (single checkbox選択またはtwo checkbox選択またはthree checkbox選択など) のいずれかの場合、正常に動作しますが、後で動作しません(uncheck上記のいずれかの基準を選択し、checkbox再度選択すると機能しないことを意味します。そのためには、アプリ/コードを更新する必要があり、それのみが機能します)。

例: Name から 1 つを選択すると、それぞれの一致したデータが表示されます。それからもう一度uncheck同じようにしたら、それcheckは機能していません。上記のすべての基準についても同様です。はっきりできます。some other checkboxDescriptionobserve

ここで間違ったことを教えてください。適切にフィルタリングする方法を教えてください。Fiddleを作成しました。前もって感謝します !

4

2 に答える 2

2

問題は、複雑なフィルタリング ロジックです。多くのステートメントを入れ子にしている場合はif、分岐ロジックを再編成することを検討してください。より小さなコンポーネントに分割することで、管理が容易になり、if完全に使用することを避けることができれば、複数ではなく 1 つのパスをテストするだけで済みます。

ユーザーがボックスをチェックするたびに、チェックボックスの数に関係なく、一致するアイテムのみを表示するようにする必要があります。したがって、1) チェックされているボックスの数 n 、および 2) n 個の一致するフィールドで見つかるアイテムの数を知る必要があります。

ブール変数を整数 (0 = false、true = 1) にキャストできるという事実を利用して、それを使用して、チェックされたボックスの数と見つかった一致の数をカウントできます。

フィールド名を配列に入れることもできるので、関数内で多くの繰り返しを避けることができます。

ここにフィドルの例があります

var fields = ["name", "description", "field4"];

//for each field, count how many fields the item matches
function getMatches(item, matchesNeeded) {
    var foundMatches = 0;
    fields.forEach(field => {
      foundMatches += item[field] === $scope.pagedItems[field]
    });

    //make sure found at least one match and found desired minimum
    return foundMatches && foundMatches >= matchesNeeded;
}

//count how many boxes are checked
//this will tell us how many different fields we are matching on
function numChecked() {
    var count = 0;
    fields.forEach(field => {
        //this will auto convert falsy to 0.
        //truthy values will be 1
        count += Boolean($scope.pagedItems[field]);
    });
    return count;
}

$scope.filterItems = function(item) {
    return getMatches(item, numChecked());
};
于 2016-11-08T15:33:05.493 に答える
1

@Larryが指摘したように、それはより論理に基づいていました。このために、 Apress book 'Pro AngularJS' Source Code from GITを修正しました。

基本的なロジックは、次のようにフィルター関数になります-

$scope.categoryFilterFn = function (product) {
    var canHave = false;//dont load by default
    var atLeastOneTrue = false;//Check if previously checked any condition
    angular.forEach(filterValues, function(selectedValue, key) {
        var selectVals = Object.values(selectedValue);
            if(selectVals.indexOf(product[key]) !== -1) {//if values exits in product.
                canHave = !atLeastOneTrue ? true : canHave;
            }else{
                canHave = false;
            }
            atLeastOneTrue = true;
    });
    return canHave;
}

Fiddle の作業用。

于 2016-11-08T18:25:43.830 に答える