过滤movielist JavaScript

时间:2018-01-25 17:02:19

标签: javascript json ajax

当我将类别与select的值进行比较时,我正在尝试过滤电影列表。但我特别关注包含多个类别的电影。

我该如何解决这个问题?

你能告诉我如何在asynchronus函数中返回数据吗?

window.addEventListener("load", setup);
var select = document.querySelector("select");

function setup() {
  var xhr = new XMLHttpRequest();
  xhr.open('GET', 'data/data.json', true);

  xhr.onreadystatechange = function() {
    if (this.readyState === 4 && this.status === 200) {
      var data = JSON.parse(this.responseText);

      var output = '';
      var genre = '<option> ' + "-- Select Genre --" + ' </option>';

      for (var i = 0; i < data.movies.length; i++) {
        output += '<ul>' +
          '<li> Title: ' + data.movies[i].title + '</li>' +
          '<li> Category: ' + data.movies[i].categories + '</li>' +
          '</ul>';
      }

      for (var i = 0; i < data.categories.length; i++) {
        genre += '<option> ' + data.categories[i] + ' </option>';
      }

      document.getElementById('output').innerHTML = output;
      document.getElementById('selection').innerHTML = genre;

      select.addEventListener('change', filter);

      function filter() {
        for (var i = 0; i < data.categories.length; i++) {
          if (data.movies[i].categories == select.value) {
            alert(2)
          }
        }
      }
    }
  }
  xhr.onerror = function() {
    console.log("req");
  }
  xhr.send();
}

我现在已经更改了它,所以类别和电影是在不同的循环中生成的,但是当选择类别时我仍然无法将class添加到ul元素我只想要显示按该类别划分的电影

我的,您可以在其中查看如何在对象中设置数据:

{
  "movies": [{
    "title": "Mad Max",
    "categories": "action"
  }, {
    "title": "Willow",
    "categories": "action,fantasy"
  }, {
    "title": "Alien",
    "categories": "action,sci-fi"
  }, {
    "title": "Silence of the lambs",
    "categories": "thriller"
  }, {
    "title": "The Ring",
    "categories": "horror"
  }, {
    "title": "Gone with the wind",
    "categories": "drama"
  }, {
    "title": "Lion King",
    "categories": "animation, family"
  }, {
    "title": "Jumanji",
    "categories": "action,fantasy, family"
  }, {
    "title": "Heat",
    "categories": "action,thriller"
  }, {
    "title": "Blade runner",
    "categories": "action,sci-fi"
  }],
  "categories": ["action", "sci-fi", "drama", "thriller", "horror", "fantasy", "family", "animation"]
}

3 个答案:

答案 0 :(得分:1)

首先,您需要一个帮助函数才能正确执行XMLHttpRequest,以便异步返回数据。例如:

var newXHR = null;

function sendXHR(options, callback) {
  newXHR = new XMLHttpRequest() || new window.ActiveXObject("Microsoft.XMLHTTP");
  options.contentType = options.contentType || "application/x-www-form-urlencoded";
  newXHR.open(options.type, options.url, true);
  newXHR.setRequestHeader("Content-Type", options.contentType);
  newXHR.send(options.data);
  newXHR.onreadystatechange = function() {
    if (this.status === 200 && this.readyState === 4) {
      callback(this.response);
    }
  };
}

在此示例中,我们将展示如何配置XMLHttpRequest对象以执行异步请求并在回调函数中分配响应。

<强>用法:

sendXHR({
  url: "https://gist.githubusercontent.com/dannyjhonston/288a0555179f379008e901d9d5f034a3/raw/03519253848040cd8c7d68dceb0e5a53755e5f52/movies.json",
  type: "GET"
}, function(response) {
  console.log(response); // Contains data from the url.
  // Performs other operations with the response.
});

使用给定的响应,使用此函数填充类别:

function fillCategories(data) {
  var selection = document.getElementById("selection"), html = "", len = data.categories.length;
  html += "<option>-- Select Genre --</option>";
  for (var i = 0; i < len; i++) {
    html += "<option value=\"";
    html += data.categories[i];
    html += "\">";
    html += data.categories[i];
    html += "</option>";
  }
  selection.innerHTML = html; // Render the html.
  selection.onchange = function() { // When the selection field is changed call the printOutput function.
    printOutput(this.value); // this.value is the selected genre.
  };
}

使用选择的流派,使用此功能填充输出:

function printOutput(genre) {
  var result = data.movies.filter(function(x) {
      return x.categories.indexOf(genre) > -1;
    }), output = document.getElementById("output"), len = result.length, html = "";
  for (var i = 0; i < len; i++) {
    html += "<li>";
    html += result[i].title;
    html += "</li>";
  }
  output.innerHTML = html;
}

在上一个功能中,我使用Array.prototype.filter()使用x.categories.indexOf (genre) > -1;返回包含与所选类别对应的电影的新数组。

这样的事情:

&#13;
&#13;
(function() {
  var newXHR = null; // Once initialized with the XMLHttpRequest object, you can use the abort() method from anywhere in the code.
  var data = {}; // This variable is declared in the global scope.

  function sendXHR(options, callback) {
    newXHR = new XMLHttpRequest() || new window.ActiveXObject("Microsoft.XMLHTTP");
    options.contentType = options.contentType || "application/x-www-form-urlencoded";
    newXHR.open(options.type, options.url, true);
    newXHR.setRequestHeader("Content-Type", options.contentType);
    newXHR.send(options.data);
    newXHR.onreadystatechange = function() {
      if (this.status === 200 && this.readyState === 4) {
        callback(this.response);
      }
    };
  }
  sendXHR({
    url: "https://gist.githubusercontent.com/dannyjhonston/288a0555179f379008e901d9d5f034a3/raw/03519253848040cd8c7d68dceb0e5a53755e5f52/movies.json",
    type: "GET"
  }, function(response) {
    data = JSON.parse(response);
    fillCategories(data);
  });

  function printOutput(genre) {
    var result = data.movies.filter(function(x) {
        return x.categories.indexOf(genre) > -1;
      }), output = document.getElementById("output"), len = result.length, html = "";
    for (var i = 0; i < len; i++) {
      html += "<li>";
      html += result[i].title;
      html += "</li>";
    }
    output.innerHTML = html;
  }

  function fillCategories(data) {
    var selection = document.getElementById("selection"),
      html = "", len = data.categories.length;
    html += "<option>-- Select Genre --</option>";
    for (var i = 0; i < len; i++) {
      html += "<option value=\"";
      html += data.categories[i];
      html += "\">";
      html += data.categories[i];
      html += "</option>";
    }
    selection.innerHTML = html;
    selection.onchange = function() {
      printOutput(this.value);
    };
  }
}());
&#13;
<select id="selection"></select>
<ul id="output"></ul>
&#13;
&#13;
&#13;

答案 1 :(得分:0)

你的逻辑中有一些错误。

  1. 循环与带有i变量的movies.length关联,但您也尝试使用它来获取类别索引。
  2. 尝试将逻辑拆分为管理类别,然后是电影。我的意思是创建2个独立的循环......

    for(var i = 0; i < data.movies.length; i++)
    {
      //movies html generation
    }
    
    for(var i = 0; i < data.categories.length; i++)
    {
      //categories html generation
    }
    

    2您的电影将类别属性包含为字符串,您将其作为数组进行尝试。

    所以在电影内部循环,做这样的事情......

    for(var i = 0; i < data.movies.length; i++)
    {
       data.movies[i].categories = data.movies[i].categories.split(',');
       //movies html generation
    }
    

    注意您可以使用导航器开发人员工具调试代码。

答案 2 :(得分:0)

&#13;
&#13;
var movieList = {
    "movies": [{
        "title": "Mad Max",
        "categories": "action"
    }, {
        "title": "Willow",
        "categories": "action,fantasy"
    }, {
        "title": "Alien",
        "categories": "action,sci-fi"
    }, {
        "title": "Silence of the lambs",
        "categories": "thriller"
    }, {
        "title": "The Ring",
        "categories": "horror"
    }, {
        "title": "Gone with the wind",
        "categories": "drama"
    }, {
        "title": "Lion King",
        "categories": "animation, family"
    }, {
        "title": "Jumanji",
        "categories": "action,fantasy, family"
    }, {
        "title": "Heat",
        "categories": "action,thriller"
    }, {
        "title": "Blade runner",
        "categories": "action,sci-fi"
    }],
    "categories": ["action", "sci-fi", "drama", "thriller", "horror", "fantasy", "family", "animation"]
}

var movieArray = movieList.movies.map(function(a) {
	return {
  	"title": a.title,
    "categories": a.categories.split(",")
  }
})

console.log(movieArray);

console.log(movieArray.filter(function(a) {
    return a.categories.includes("thriller")
}));
&#13;
&#13;
&#13;

希望这可以帮助您进行数据格式化。