У меня проблемы с написанием логики этого кода. Я проанализировал данные из этого большой api.
Код в настоящее время извлекает все названия программ (есть несколько экземпляров одного и того же названия) и сравнивает их с массивом ночных шоу, а затем распечатывает их один раз в собственном теге <p>.
Я бы хотел как-нибудь щелкните заголовок программы и отобразите дополнительные данные JSON.
Я подумал сравнить <p> innerHTML с переменной title, и при щелчке по его div вернуть список гостей для этой конкретной программы. Я играл с логикой и не слишком уверен, что на правильном пути.
var data = JSON.parse(request.responseText);
var set = new Set();
var x = '';
const lateNightHosts = ['The Late Show with Stephen Colbert', 'Conan', 'Jimmy Kimmel Live'];
class TVProgram {
constructor(title, guests) {
this.title = title;
this.guests = guests;
}
// Gets title instance once to display in view
getShow(array) {
let programs = document.getElementById('programs');
let elem = '';
if (array.indexOf(this.title) !== -1){
if (!set.has(this.title)) {
set.add(this.title);
}
set.forEach((value) => {
elem += cardTemplate(value)
});
programs.innerHTML = elem;
}
getLineup() {
// if div is clicked, get name in <p>
// if name == title variable, print guests
}
}
function cardTemplate(value) {
return `
<div class = "cards">
<p class = "host">${value}</p>
</div>
`
}
//...
for (x in data){
// JSON properties
let title = data[x]._embedded.show.name;
let guests = data[x].name;
let latenight = new TVProgram(title, guests);
latenight.getShow(lateNightHosts);
}
Я бы хотел придерживаться ванильного JavaScript. Относительно новичок в языке, заранее спасибо!
Я упоминал выше, я пытаюсь отобразить данные guest, когда я нажимаю на выведенную программу title. Я написал псевдокод там, где должен быть фактический код, а также написал псевдокод в объяснении выше.
Похоже, вам нужен прослушиватель событий щелчка. Что именно вы хотите сравнить в вашем методе getLineup? Вы можете создать обычный делегированный прослушиватель событий с e в качестве аргумента, а затем проверить свойство e.targettextContent. Я был бы признателен за дополнительную информацию здесь. Можете ли вы предоставить пример сгенерированного HTML вместе с тем, что вы хотите, чтобы ваш код делал и выводил?
Я думаю, вы упускаете здесь несколько серьезных моментов. Во-первых, похоже, что каждый созданный вами объект TVProgram будет повторен и протестирован. Со временем это приведет к высокому потреблению памяти. Во-вторых, большая часть вашего кода в getShow отфильтровывает данные, что можно сделать с помощью базовых функций массива перед, которые вы создаете для объектов TVProgram. В этом случае вы выполняете запрос DOM внутри объекта TVProgram, который представляет TVProgram, который является антипаттерном.
@Xufox array будет использоваться для сравнения titles из данных JSON со строками arraylateNightShows, но я не уверен, как (если) эта функция будет работать, поэтому на данный момент я удалил ее. То, что вы говорите, больше похоже на то, что я ищу, мне нужно больше узнать об этом
@Leroy Спасибо, то, что ты говоришь, имеет смысл. Я новичок в этом, поэтому мне понадобится время, чтобы выяснить правильную структуру
Вам следует узнать больше о фильтрации данных, манипуляциях с DOM и событиях. Потому что мне кажется, это то, что вы ищете. Если вы хотите пропустить ванильный js, вам следует рассмотреть хотя бы jQuery. Просто чтобы узнать о некоторых основах, прежде чем вы усердно изучите vanilla js.



![Безумие обратных вызовов в javascript [JS]](https://i.imgur.com/WsjO6zJb.png)


Я прочитал то, что вы хотели, и придумал свой подход. Здесь вы можете увидеть рабочую копию https://jsfiddle.net/sm42xj38/
const lateNightHosts = ['The Late Show with Stephen Colbert', 'Conan', 'Jimmy Kimmel Live'];
class TVProgram {
constructor(data) {
this.data = data;
this.popup = this.popup.bind(this); // this is required because I'm setting this.popup as the callback for click
}
popup(){
// Just a simple alert which pretty prints all the JSON data for this TVProgram
alert(JSON.stringify(this.data, null, 10));
}
render(){
const {name} = this.data;
let card = document.createElement('div');
card.className = "cards";
let host = document.createElement('p');
host.className = "host";
// When the user clicks the element, the popup() function is called on this specific object. This specific object has the data for 1 TVProgram.
host.addEventListener('click', this.popup);
// above event could also be, then the binding in the constructor is not required.
// host.addEventListener('click', function() { this.popup() });
host.textContent = name;
card.append(host);
return card;
}
}
// call the API
axios.get('https://api.tvmaze.com/schedule/full').then(response => {
return response.data;
})
.then(data => {
// filter the shows only available in the lateNightHosts list
return data.filter(m => ~lateNightHosts.indexOf(m._embedded.show.name));
})
.then(shows => {
// Create a TVProgram for each of the filtered shows
return shows.map(show => new TVProgram(show));
})
.then(programs => {
// Add every TVProgram to a DOM element
programs.forEach(program => {
document.getElementById("shows").appendChild(program.render());
})
})
Как видите, я использую axios в качестве http-клиента, потому что в нем меньше кода.
Это ОЧЕНЬ ОЧЕНЬ слабо основано на том, как работает React, с методом рендеринга в классе TVProgram. Я не использую шаблоны из-за сложности шаблона. Событие основано на элементе dom, который привязан к TVProgram, который имеет только данные этого конкретного шоу. Поэтому все данные хранятся в памяти, а не в DOM.
в чем проблема ?