简体   繁体   English

AngularJS-通过3个选择输入过滤阵列

[英]AngularJS - Filter Array Via 3 Select Inputs

My first AngularJS App... 我的第一个AngularJS应用...

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

I'm trying to achieve the following functionality: 我正在尝试实现以下功能:

  1. Select either 'Solo Artist' or 'Band' from select box 1 从选择框1中选择“独奏艺术家”或“乐队”
  2. Once that selection has been made, the following should appear in select box 2: 做出选择后,以下内容应出现在选择框2中:

    • 'Solo Artist' -> One Song (Vocal And Instrument) or One Song (Vocal To Pre-Recorded Backing Track) “独奏艺术家”-> One Song (Vocal And Instrument)One Song (Vocal To Pre-Recorded Backing Track)
    • 'Band' -> EP or One Song '乐队'-> EPOne Song
  3. Once that selection has been made, the following number of options should appear in select box 3: 做出选择后,选择框3中应显示以下数量的选项:

    • 'Solo Artist' -> 'One Song (Vocal And Instrument)': 3 “独奏艺术家”->“一首歌(人声和乐器)”: 3
    • 'Solo Artist' -> 'One Song (Vocal To Pre-Recorded Backing Track)': 13 “独奏艺术家”->“一首歌(声音到预先录制的伴奏音轨)”: 13
    • 'Band' -> 'One Song': 2 '乐队'->'一首歌': 2
    • 'Band' -> 'EP': 1 '频段'->'EP': 1

So far I have everything working up to step 2. However, looping over postsFiltered the second time seems to break everything. 到目前为止,我已经完成了第2步的所有工作。但是,第二次遍历postsFiltered似乎会破坏一切。 The array seems to get filtered twice in one digest (see console log in Plunker ), removing all of its contents. 该数组似乎在一个摘要中被过滤了两次(请参阅Plunker中的控制台日志),删除了所有内容。 The contents of the select boxes also gets mixed up; 选择框的内容也会混淆。 moving focus to select box 3 removes select box 2's content. 将焦点移至选择框3会删除选择框2的内容。

My questions: 我的问题:

  1. Is this the best way to go about doing something like this anyway (ie cloning an array and filtering it based on matches until there is only one object left in it)? 这是否是进行类似操作的最佳方法(即克隆一个数组并根据匹配项对其进行过滤,直到只剩下一个对象)?
  2. Should I be using multiple arrays instead (ie creating an array for each step of the process? Is using one array robust enough, or should I be taking a different approach? 我是否应该使用多个数组(即为过程的每个步骤创建一个数组?使用一个数组是否足够健壮,还是应该采用其他方法?
  3. At the moment, select box 3 gets populated along with select box 2 after a selection has been made from select box 1 and I'm not sure why. 目前,在从选择框1中进行选择后,选择框3随选择框2一起填充,我不确定为什么。 What do I need to do so they get populated sequentially instead? 我需要怎么做才能使它们依次填充? I'll be hiding select boxes before they're required, but would still like nice clean code all the same. 我将在需要选择框之前将其隐藏,但仍然希望使用干净的代码。

data.json 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"
}]

basic HTML 基本HTML

<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>

app.js app.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);

    }

}]);

You can do this mostly in the markup, here's a plnkr 您主要可以在标记中执行此操作,这是一个plnkr

Form : 形式

<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>

List : 清单

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

The only code left in the controller is to get the posts ($http) 控制器中剩下的唯一代码是获取帖子($ http)

You could probably also do without 'angular-filter' but if you're using it anyway, it's convenient. 您可能也可以不使用“角度过滤器”,但是如果您仍在使用它,它将很方便。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM