AngularJS - 通过 3 个选择输入过滤数组

AngularJS - Filter Array Via 3 Select Inputs

本文关键字:输入 过滤 数组 选择 通过 AngularJS      更新时间:2023-09-26

我的第一个AngularJS应用程序...

http://plnkr.co/edit/KJoGFWjrAwHHPOZkHxAV?p=preview

我正在尝试实现以下功能:

  1. 从选择框 1 中选择"独奏艺术家"或"乐队"
  2. 做出该选择后,选择框 2 中应显示以下内容:

    • "独奏艺术家" -> One Song (Vocal And Instrument)One Song (Vocal To Pre-Recorded Backing Track)
    • "乐队" -> EPOne Song
  3. 进行该选择后,选择框 3 中应显示以下数量的选项:

    • "独唱艺术家"->"一首歌(声乐和乐器)":3
    • "独奏艺术家"->"一首歌(人声到预先录制的背景音乐)":13
    • "乐队"->"一首歌":2
    • "乐队" -> "EP": 1

到目前为止,我已经完成了第 2 步的所有工作。然而,第二次循环postsFiltered似乎打破了一切。该数组似乎在一个摘要中被过滤了两次(请参阅 Plunker 中的控制台日志),删除了它的所有内容。选择框的内容也会混淆;将焦点移动到选择框 3 将删除选择框 2 的内容。

我的问题:

  1. 无论如何,这是执行此类操作的最佳方法(即克隆数组并根据匹配项对其进行过滤,直到只剩下一个对象)?
  2. 我应该改用多个数组(即为流程的每个步骤创建一个数组)吗?使用一个阵列是否足够强大,还是应该采用不同的方法?
  3. 目前,从选择框
  4. 3 中进行选择后,选择框 1 与选择框 2 一起填充,我不确定为什么。我需要做什么才能按顺序填充它们?我会在需要之前隐藏选择框,但仍然希望漂亮的干净代码。

data.json

[{
    "postId": 1094,
    "postSlug": "band-ep-1-hour",
    "postTitle": "Band: EP – 1 Hour",
    "postTitleName": "Band",
    "postTitleItem": "EP",
    "postTitleTime": "1 Hour"
}, {
    "postId": 1093,
    "postSlug": "band-one-song-2-hours",
    "postTitle": "Band: One Song – 2 Hours",
    "postTitleName": "Band",
    "postTitleItem": "One Song",
    "postTitleTime": "2 Hours"
}, {
    "postId": 1092,
    "postSlug": "band-one-song-1-hour",
    "postTitle": "Band: One Song – 1 Hour",
    "postTitleName": "Band",
    "postTitleItem": "One Song",
    "postTitleTime": "1 Hour"
}, {
    "postId": 1076,
    "postSlug": "solo-artist-one-song-vocal-and-instrument-3-hours",
    "postTitle": "Solo Artist: One Song (Vocal And Instrument) – 3 Hours",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal And Instrument)",
    "postTitleTime": "3 Hours"
}, {
    "postId": 1071,
    "postSlug": "solo-artist-one-song-vocal-and-instrument-2-hours",
    "postTitle": "Solo Artist: One Song (Vocal And Instrument) – 2 Hours",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal And Instrument)",
    "postTitleTime": "2 Hours"
}, {
    "postId": 1069,
    "postSlug": "solo-artist-one-song-vocal-and-instrument-1-hour",
    "postTitle": "Solo Artist: One Song (Vocal And Instrument) – 1 Hour",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal And Instrument)",
    "postTitleTime": "1 Hour"
}, {
    "postId": 1066,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-320-hours-40-days",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 320 Hours (40 Days)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "320 Hours (40 Days)"
}, {
    "postId": 1065,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-160-hours-20-days",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 160 Hours (20 Days)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "160 Hours (20 Days)"
}, {
    "postId": 1064,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-80-hours-10-days",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 80 Hours (10 Days)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "80 Hours (10 Days)"
}, {
    "postId": 1063,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-40-hours-5-days",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 40 Hours (5 Days)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "40 Hours (5 Days)"
}, {
    "postId": 1062,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-32-hours-4-days",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 32 Hours (4 Days)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "32 Hours (4 Days)"
}, {
    "postId": 1061,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-24-hours-3-days",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 24 Hours (3 Days)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "24 Hours (3 Days)"
}, {
    "postId": 1060,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-16-hours-2-days",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 16 Hours (2 Days)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "16 Hours (2 Days)"
}, {
    "postId": 1059,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-8-hours-1-day",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 8 Hours (1 Day)",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "8 Hours (1 Day)"
}, {
    "postId": 1057,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-6-hours",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 6 Hours",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "6 Hours"
}, {
    "postId": 1056,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-4-hours",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 4 Hours",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "4 Hours"
}, {
    "postId": 1055,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-3-hours",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 3 Hours",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "3 Hours"
}, {
    "postId": 1053,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-2-hours",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 2 Hours",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "2 Hours"
}, {
    "postId": 1043,
    "postSlug": "solo-artist-one-song-vocal-to-pre-recorded-backing-track-1-hour",
    "postTitle": "Solo Artist: One Song (Vocal To Pre-Recorded Backing Track) – 1 Hour",
    "postTitleName": "Solo Artist",
    "postTitleItem": "One Song (Vocal To Pre-Recorded Backing Track)",
    "postTitleTime": "1 Hour"
}]

基本网页

<form>
    <fieldset id="app-contents-form-fieldset-1">
        <label for="entry-names">I want to record as a...</label>
        <select id="entry-names" ng-model="selected.name" ng-options="data.postTitleName as data.postTitleName for data in posts | unique:'postTitleName' track by data.postTitleName" ng-focus="selectedNameFocus()" ng-change="selectedNameChoice()">
            <option value="" default="" selected="selected">Please Choose...</option>
        </select>
    </fieldset>
    <fieldset id="app-contents-form-fieldset-2" ng-show="showFieldset2">
        <label for="entry-items">I want to record...</label>
        <select id="entry-items" ng-model="selected.item" ng-options="data.postTitleItem as data.postTitleItem for data in postsFiltered | unique:'postTitleItem' track by data.postTitleItem" ng-focus="selectedItemFocus()" ng-change="selectedItemChoice()">
            <option value="" default="" selected="">Please Choose...</option>
        </select>
    </fieldset>
    <fieldset id="app-contents-form-fieldset-3" ng-show="showFieldset3">
        <label for="entry-times">I want to spend this much time...</label>
        <select id="entry-times" ng-model="selected.time" ng-options="data.postTitleTime as data.postTitleTime for data in posts | unique:'postTitleTime' track by data.postTitleTime" ng-focus="selectedTimeFocus()" ng-change="doResult()">
            <option value="" default="" selected="">Please Choose...</option>
        </select>
    </fieldset>
</form>

应用.js

var bookingStudioTime = angular.module('bookingStudioTime', ['angular.filter']);
bookingStudioTime.controller('mainController', ['$scope', '$http', '$filter', function($scope, $http, $filter) {
  $http.get('data.json').success(function(ret) {
      $scope.posts = ret;
  });
    $scope.selectedNameFocus = function() {
      $scope.showFieldset2 = true;
      $scope.showFieldset3 = true;
        $scope.postsFiltered = angular.copy($scope.posts);
    };
    $scope.selectedNameChoice = function() {
      $scope.showFieldset2 = true;
        for ( var i = $scope.postsFiltered.length - 1; i >= 0; i-- ) {
            if ( $scope.postsFiltered[i].postTitleName !== $scope.selected.name ) {
                $scope.postsFiltered.splice(i, 1);
                console.log($scope.postsFiltered);
            }
        }
        $scope.postsFilteredItems = $scope.postsFiltered;
    };
    $scope.selectedItemChoice = function() {
      $scope.showFieldset3 = true;
        for ( var i = $scope.postsFiltered.length - 1; i >= 0; i-- ) {
            if ( $scope.postsFiltered[i].postTitleItem !== $scope.selected.item ) {
                $scope.postsFiltered.splice(i, 1);
                console.log($scope.postsFiltered);
            }
        }
        $scope.postsFilteredItems = $scope.postsFiltered;
    };
    $scope.doResult = function() {
        for ( var i = $scope.postsFiltered.length - 1; i >= 0; i-- ) {
            if ( $scope.postsFiltered[i].postTitleTime !== $scope.selected.time ) {
                $scope.postsFiltered.splice(i, 1);
            }
        }
        $scope.selected.id = $scope.postsFiltered[0].postId;
        console.log($scope.selected.id);
    }
}]);

你可以主要在标记中做到这一点,这是一个 plnkr

形式

<form>
    <fieldset id="app-contents-form-fieldset-1">
        <label for="entry-names">I want to record as a...</label>
        <select id="entry-names" ng-model="selected.name" ng-options="data.postTitleName as data.postTitleName for data in posts | unique:'postTitleName' track by data.postTitleName" ng-focus="selectedNameFocus()" ng-change="selectedNameChoice()">
            <option value="" default="" selected="selected">Please Choose...</option>
        </select>
    </fieldset>
    <fieldset id="app-contents-form-fieldset-2" ng-show="selected.name">
        <label for="entry-items">I want to record...</label>
        <select id="entry-items" ng-model="selected.item" ng-options="data.postTitleItem as data.postTitleItem for data in posts | filter: {postTitleName: selected.name} | unique:'postTitleItem' track by data.postTitleItem" ng-focus="selectedItemFocus()" ng-change="selectedItemChoice()">
            <option value="" default="" selected="">Please Choose...</option>
        </select>
    </fieldset>
    <fieldset id="app-contents-form-fieldset-3" ng-show="selected.name && selected.item">
        <label for="entry-times">I want to spend this much time...</label>
        <select id="entry-times" ng-model="selected.time" ng-options="data.postTitleTime as data.postTitleTime for data in posts | filter: {postTitleName: selected.name, postTitleItem: selected.item} | unique:'postTitleTime' track by data.postTitleTime" ng-focus="selectedTimeFocus()" ng-change="doResult()">
            <option value="" default="" selected="">Please Choose...</option>
        </select>
    </fieldset>
</form>

列表

<ELEMENT ng-repeat="post in posts | filter: {postTitleName: selected.name, postTitleItem: selected.item, postTitleTime: selected.time}">

控制器中剩下的唯一代码是获取帖子($http)

您可能也可以不使用"角度过滤器",但如果您无论如何都要使用它,这很方便。