次の3つの操作を実行しようとしています。
- の各アイテムからタグの配列を取得します
$scope.list
- これらを単一の配列にフラット化します
- この配列から一意の値を取得します
これは純粋なJavaScriptで行うことができますが、作業を簡単にするために、配列やオブジェクトなどを操作および検査するための多くの関数にアクセスできるライブラリであるアンダースコアを使用することをお勧めします。
このコードから始めましょう:
$scope.list = [
{id: 0, tags: ['tag1', 'tag2']},
{id: 1, tags: ['tag2']},
{id: 2, tags: ['tag1', 'tag3', 'tag4']},
{id: 3, tags: ['tag3', 'tag4']}
];
それでは、最初の操作を実行しましょう。のtags
各オブジェクトのプロパティから配列を取得します$scope.list
。アンダースコアはpluck
メソッドを提供します。これはまさに私たちが必要としているものです。
摘む _.pluck(list, propertyName)
マップのおそらく最も一般的なユースケースの便利なバージョン:プロパティ値のリストの抽出。
pluckを使用すると、次のようになります。
var tags = _.pluck($scope.list, 'tags');
// gives us [['tag1', 'tag2'], ['tag2'], ['tag1', 'tag3', 'tag4'], ['tag3', 'tag4']]
次に、その配列をフラット化します。
平らにする _.flatten(array, [shallow])
ネストされた配列をフラット化します(ネストは任意の深さにすることができます)。浅く通過すると、配列は1レベルだけ平坦化されます。
tags = _.flatten(tags);
// gives us ['tag1', 'tag2', 'tag2', 'tag1', 'tag3', 'tag4', 'tag3', 'tag4']
最後に、各タグのインスタンスは1つだけ必要です。
uniq _.uniq(array, [isSorted], [iterator])
エイリアス:unique
===を使用してオブジェクトの同等性をテストし、重複のないバージョンの配列を生成します。配列がソートされていることが事前にわかっている場合、isSortedにtrueを渡すと、はるかに高速なアルゴリズムが実行されます。変換に基づいて一意のアイテムを計算する場合は、イテレータ関数を渡します。
tags = _.unique(tags)
// gives us ['tag1', 'tag2', 'tag3', 'tag4']
これらをUnderscoreの便利な方法と組み合わせて、これらchain
を連鎖させることができます。一意のタグを返すスコープ上に関数を作成しましょう。
$scope.uniqueTags = function() {
return _.chain($scope.list)
.pluck('tags')
.flatten()
.unique()
.value();
};
これは関数であるため、事後にアイテムを追加または削除しても、常に一意のタグが返されます$scope.list
。
ng-repeat
これで、を使用しuniqueTags
て各タグを表示できます。
<div ng-repeat="tag in uniqueTags()">
<label class="checkbox">
<input type="checkbox" ng-model="filter.tag" />
{{tag}}
</label>
</div>
これは、この手法を示す実用的なjsFiddleです。http://jsfiddle.net/BinaryMuse/cqTKG/