【问题标题】:Creating a javascript notes app but note prints more than once?创建一个 javascript 笔记应用程序但笔记打印不止一次?
【发布时间】:2023-02-11 22:36:08
【问题描述】:

我是 javascript 的新手。我正在尝试创建一个 notesapp,其中包含用户输入的笔记。到目前为止,我能够添加和显示注释,但每个注释都显示两次,例如,如果我输入“你好”,它会打印出你好,但如果我输入“再见”,它会打印出“你好,你好,再见。”我在下面打印了我的代码以及我的视图和模型类。

class NotesView{
    constructor(model){
        this.model = model;
        this.mainContainerEL = document.querySelector('#main-container');
        this.noteButton = document.querySelector('#add-note');

        this.noteButton.addEventListener('click', () => { this.addNewNote() });
    }
    

    addNewNote(){
        const new_note = document.getElementById('message').value;
        
        this.model.addNote(new_note);

        this.displayNotes();
      
    }

    displayNotes() {     
        const notes = this.model.getNotes();
       
        notes.forEach(note =>{
            
            const noteEl = document.createElement('div'); 
            noteEl.textContent = note;                    
            noteEl.className = 'note';                   
            this.mainContainerEL.append(noteEl);        
        })
        
    }
}
module.exports = NotesView;

class notesModel{
    constructor(notes){
        this.notes = []
    }

    getNotes(){
        return this.notes
    }

    addNote(note){
       return this.notes.push(note)
    }
    
    reset(){
        this.notes.splice(0, this.notes.length)
    }

}

module.exports = notesModel;

【问题讨论】:

    标签: javascript class dom


    【解决方案1】:

    正如 Mushroomator 所说,您每次添加注释时都会附加整个模型注释。 所以你要么

    • 在添加所有这些注释之前清除容器。
    • 将新注释添加到模型后立即显示它们。
    • 为模型添加索引以仅显示最新的笔记 索引解决方案是这样的

    class NotesView {
      constructor(model) {
        this.model = model;
        this.mainContainerEL = document.querySelector("#main-container");
        this.noteButton = document.querySelector("#add-note");
        this.noteButton.addEventListener("click", () => {
          this.addNewNote();
        });
      }
    
      addNewNote() {
        const new_note = document.getElementById("message").value;
    
        this.model.addNote(new_note);
    
        this.displayNotes();
      }
    
      displayNotes() {
        const notes = this.model.getNotes();
        for (let i = this.model.displayindex; i < notes.length; i++) {
          const noteEl = document.createElement("div");
          noteEl.textContent = notes[i];
          noteEl.className = "note";
          this.mainContainerEL.append(noteEl);
          this.model.displayindex++;
        }
      }
    }
    
    class notesModel {
      constructor(notes) {
        this.notes = [];
        this.displayindex = 0;
      }
    
      getNotes() {
        return this.notes;
      }
    
      addNote(note) {
        return this.notes.push(note);
      }
    
      reset() {
        this.notes.splice(0, this.notes.length);
        this.displayindex = 0;
      }
    }
    let myNotes = new NotesView(new notesModel())
    
    
      
    <button id="add-note">Add a second note</button>
    <input type="text" id="message"/>
    <div id="main-container">
      <div>hello<span> 
    <div/>

    【讨论】:

      【解决方案2】:

      问题是你不是“重置”的DOM。每次你点击按钮addNewNote()都会被调用,它会调用displayNotes()displayNotes() 将始终为 notes 数组中的所有元素创建一个新的 div,并将该 div 附加到 #main-container 元素。

      因此,在第一次单击按钮时,数组将包含 hello 和一个用于显示 hello 的 div 将附加到容器中。到目前为止,一切都很好。

      现在,在第二次单击时,您将向数组添加另一个元素,因此它将包含 ["hello", "goodbye"]。您将为这些元素创建另外两个 div,并将其附加到容器中。因此,容器现在具有三个元素:你好div 从第一次点击和一个你好再见div 从第二次点击,这就是为什么你会看到 hello, hello, goodbye

      这是一个展示错误的最小示例:

      document.querySelector("#button").addEventListener("click", () => addSecondNote())
      const notes = ["hello", "goodbye"];
      
      function addSecondNote(){
        const container = document.querySelector("#container");
        notes.forEach(note => {
          const noteDiv = document.createElement("div");
          noteDiv.textContent = note;
          container.append(noteDiv);
        });
      }
      <button id="button">Add a second note</button>
      <div id="container">
        <div>hello<span> 
      <div/>

      解决此问题的许多可能方法之一是使用 replaceChildren(),它将采用 NodestringIterable 作为参数。您可以使用 map() 创建一个子数组 divs。

      document.querySelector("#button").addEventListener("click", () => addSecondNote())
      const notes = ["hello", "goodbye"];
      
      function addSecondNote(){
        const container = document.querySelector("#container");
        const newChildDivs = notes.map(note => {
          const noteDiv = document.createElement("div");
          noteDiv.textContent = note;
          return noteDiv;
        });
        container.replaceChildren(...newChildDivs);
      }
      <button id="button">Add a second note</button>
      <div id="container">
        <div>hello<span> 
      <div/>

      【讨论】:

      • 谢谢,我更好地理解了这个概念
      【解决方案3】:

      class NotesView {
        constructor(model) {
          this.model = model;
          this.mainContainerEL = document.querySelector("#main-container");
          this.noteButton = document.querySelector("#add-note");
          this.noteButton.addEventListener("click", () => {
            this.addNewNote();
          });
        }
      
        addNewNote() {
          const new_note = document.getElementById("message").value;
      
          this.model.addNote(new_note);
      
          this.displayNotes();
        }
      
        displayNotes() {
          const notes = this.model.getNotes();
          for (let i = this.model.displayindex; i < notes.length; i++) {
            const noteEl = document.createElement("div");
            noteEl.textContent = notes[i];
            noteEl.className = "note";
            this.mainContainerEL.append(noteEl);
            this.model.displayindex++;
          }
        }
      }
      
      class notesModel {
        constructor(notes) {
          this.notes = [];
          this.displayindex = 0;
        }
      
        getNotes() {
          return this.notes;
        }
      
        addNote(note) {
          return this.notes.push(note);
        }
      
        reset() {
          this.notes.splice(0, this.notes.length);
          this.displayindex = 0;
        }
      }
      let myNotes = new NotesView(new notesModel())
      
      
        
      <button id="add-note">Add a second note</button>
      <input type="text" id="message"/>
      <div id="main-container">
        <div>hello<span> 
      <div/>

      【讨论】:

        猜你喜欢
        • 2012-10-26
        • 1970-01-01
        • 1970-01-01
        • 2011-03-16
        • 2022-01-23
        • 1970-01-01
        • 2018-07-14
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多