简体   繁体   English

需要帮助在单击按钮时更改数组中 object 中的值

[英]Need help changing a value in an object within an array on the click of a button

I'm building a book library and need help adjusting the "read" value for an object in the myLibrary array.我正在构建一个图书库,需要帮助调整 myLibrary 数组中 object 的“读取”值。 When I click on the parent element's read status div, if the associated object's current read value is true it should change to false and vise versa.当我单击父元素的读取状态 div 时,如果关联对象的当前读取值为 true,则它应该更改为 false,反之亦然。 I added a function so when I click on the "read" div, it changes the read value for the object associated with it in the myLibrary array.我添加了一个 function,所以当我单击“读取”div 时,它会更改 myLibrary 数组中与之关联的 object 的读取值。 The issue I'm running into is that it will only change the read value for the object in the array from true to false.我遇到的问题是它只会将数组中 object 的读取值从 true 更改为 false。 If I click on the div and its associated object already has a read value of false nothing changes.如果我单击 div 及其关联的 object 的读取值已经为 false,则没有任何变化。 The object's read value just stays false.对象的读取值保持为假。 The function I need help with is within the createCard() at the bottom where I create the "read" div.我需要帮助的 function 在底部的 createCard() 中创建“读取”div。 Please help!请帮忙! Thank you!谢谢!

const library = document.querySelector('#library');

let myLibrary = [];


class Book {
  constructor(title, author, pages, read) {
    this.title = title;
    this.author = author;
    this.pages = pages;
    this.read = read;
  }
}

Book.prototype.addToLibrary = function () {
  myLibrary.push(this)
}

// myLibrary.push(new Book("The Hobbit", "J. R. R. Tolken", 471, read));
// myLibrary.push(new Book("Harry Potter", "J. K. Rowling", 381, read));
// myLibrary.push(new Book("Greenlights", "Matthew McConaughey", 252, read));

// submits the form
const addToLibraryBtn = document.querySelector('.modal-add-btn');

addToLibraryBtn.addEventListener('click', () => {
  const input = document.querySelectorAll('input')
  const title = input[0].value;
  const author = input[1].value;
  const pages = input[2].value;
  const read = document.getElementById('read').value === "Yes" ? true : false;

  const book = new Book(title, author, pages, read)
  book.addToLibrary()
  clearLibrary()
  createStoredCards()
  closeModal()
  clearForm()
})

// clears the display and re-adds cards in myLibrary array so duplicate cards are not created
const clearLibrary = () =>
  library.innerHTML = ""

// clears form inputs
const clearForm = () => {
  const form = document.querySelector('form')
  form.reset()
}

// Creates the look of the card and information that each card displays
function createCard(book) {

  const card = document.createElement('div');
  card.classList.add('card');

  // Adding the remove button and function
  const removeBtn = document.createElement('div');
  removeBtn.classList.add('remove-btn');
  removeBtn.innerText = 'Remove';
  card.appendChild(removeBtn);

  // Removes card from the array and the display
  removeBtn.addEventListener('click', () => {
    deleteBook(myLibrary.indexOf(book), card)
  })

  // Adding the title 
  let title = document.createElement('div');
  title.classList.add('card-title');
  title.innerHTML = `Title: <span>${book.title}</span>`;
  card.appendChild(title);

  // Adding the author
  let author = document.createElement('div');
  author.classList.add('card-author');
  author.innerHTML = `Author: <span>${book.author}</span>`;
  card.appendChild(author);

  // Adding the page count
  let pages = document.createElement('div');
  pages.classList.add('card-count');
  pages.innerHTML = `Page Count: <span>${book.pages}</span>`;
  card.appendChild(pages);

  // Adding the read status
  let read = document.createElement('div');
  read.classList.add('card-read');
  read.innerHTML = `Read Status: <span class="read-status">${book.read === true ? "Read" : "Not read"}</span>`;
  card.appendChild(read);
  read.addEventListener('click', () => {
    myLibrary[myLibrary.indexOf(book)].read = true ? false : true;

    clearLibrary()
    createStoredCards()
  })

  library.appendChild(card);
}

// creates a card for each book in the myLibrary array and displays the card in the users library
function createStoredCards() {
  myLibrary.forEach(book => {
    createCard(book);
  })
}

// function that removes book
function deleteBook(bookIndex, card) {
  myLibrary.splice(bookIndex, 1);
  card.remove();
}

// Open and close modal form

const addBookBtn = document.querySelector('.add-btn');
const modal = document.querySelector('.modal');
const closeBtn = document.querySelector('.close-modal');

addBookBtn.addEventListener('click', () => {
  modal.style.display = "flex";
})

const closeModal = () => modal.style.display = 'none'

window.addEventListener('click', (e) => {
  if (e.target == modal) {
    closeModal();
  }
})

closeBtn.addEventListener('click', () => {
  closeModal();
})

The problem is in your ternary conditional operator, here:问题出在您的三元条件运算符中,这里:

read.addEventListener('click', () => {
  myLibrary[myLibrary.indexOf(book)].read = true ? false : true;

  clearLibrary()
  createStoredCards()
})

When you write ...read = true? false: true当你写...read = true? false: true ...read = true? false: true , this is what happens: ...read = true? false: true ,这就是发生的事情:

  1. This is an assignment statement ( = ), so it will evaluate all that is at the rigt of the assignment operator;这是一个赋值语句( = ),因此它将评估赋值运算符的所有内容;
  2. Then you have your ternary conditional operator .然后你有你的三元条件运算符 It works like this:它是这样工作的:
  • It check if the expression before ?它检查是否之前的表达式? (called condition) evaluates to true or false . (称为条件)评估为truefalse
  • If the condition evaluates to true (see truthy ), the result of the ternary expression is whatever is before the : .如果条件的计算结果为true (请参阅truthy ),则三元表达式的结果是:之前的结果。
  • If the condition evaluates to false (see falsy ), the result of the ternary expression is whatever is after the : .如果条件计算结果为false (请参阅falsy ),则三元表达式的结果是:之后的任何内容。
  1. In your case, it is true? false: true在你的情况下,这是true? false: true true? false: true . true? false: true The condition here is simply the constant true , which always evaluates to true .这里的条件只是常量true ,它总是计算为true Hence, the result of the ternary expression will always be false , and that will be assigned to the .read property on every click.因此,三元表达式的结果将始终为false ,并将在每次点击时分配给.read属性。

To fix your code, you have to check inside the condition expression, if .read is truthy.要修复您的代码,您必须检查条件表达式内部,如果.read是真的。 Like this:像这样:

wasRead = myLibrary[myLibrary.indexOf(book)].read
myLibrary[myLibrary.indexOf(book)].read = wasRead ? false : true;

But actually, the operation you are doing is a very common one, know as "toggle".但实际上,您正在执行的操作是一种非常常见的操作,称为“切换”。 For toggling a boolean value, you just need to negate ( ! ) is current value (if you do !true , you get false , and vice versa).要切换 boolean 值,您只需要否定 ( ! ) 是当前值(如果你这样做!true ,你会得到false ,反之亦然)。

wasRead = myLibrary[myLibrary.indexOf(book)].read
myLibrary[myLibrary.indexOf(book)].read = !wasRead

Moreover, I don't see the point of this big expression to get the .read property of book by getting the index on the librady.此外,我看不出这个大表达式的意义在于通过获取图书馆上的索引来获取book.read属性。 You already have a reference to the book object?您已经参考了 object 这本书? Why not just this?为什么不只是这个?

book.read = !book.read

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

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