2017-01-13 1 views
0

Ich mache eine grundlegende Einkaufsliste App und habe in eine Wand gerannt. Das Programm schlägt automatisch fehl, und nachdem ich mit Haltepunkten und dergleichen überprüft habe, habe ich festgestellt, dass in Zeile 75 newItem als undefiniert angezeigt wird.Warum bekomme ich undefiniert für diese mit jQuery .val() zugewiesene Variable?

Alles andere in der Anweisung wird korrekt definiert. Irgendwelche Hinweise, was ich falsch gemacht habe?

Hier ist die index.js:

'use strict'; 

var state = { 
    items: [] 
}; 

var listItemTemplate = (
    '<li>' + 
     '<span class="shopping-item js-shopping-item"></span>' + 
     '<div class="shopping-item-controls">' + 
      '<button class="js-shopping-item-toggle">' + 
       '<span class="button-label">check</span>' + 
      '</button>' + 
      '<button class="js-shopping-item-delete">' + 
       '<span class="button-label">delete</span>' + 
      '</button>' + 
      '</div>' + 
    '</li>' 
); 

// state modification functions 
var stateHelper = { 
    addItem: function(state, item) { 
     state.items.push({ 
      displayName: item, 
      checkedOff: false 
     }); 
    }, 
    getItem: function(state, itemIndex) { 
     return state.items[itemIndex]; 
    }, 
    deleteItem: function(state, item) { 
     state.items.splice(itemIndex, 1); 
    }, 
    updateItem: function(state, item) { 
     state.items[itemIndex] = newItemState; 
    } 
} 

// render functions 
var renderHelper = { 
    renderItem: function(item, itemId, itemTemplate, itemDataAttr) { 
     var element = $(itemTemplate); 
     element.find('.js-shopping-item').text(item.displayName); 
     console.log("item.displayName: " + item.displayName) 
     console.log("item: " + item) 
     if (item.checkedOff) { 
      element.find('.js-shopping-item').addClass('shopping-item__checked'); 
     } 
     element.find('.js-shopping-item-toggle') 
     element.attr(itemDataAttr, itemId); 
     // try `element.find('.js-shopping-item-toggle').attr(itemDataAttr, itemId);` instead and see if it works 
     console.log("itemDataAttr: " + itemDataAttr) 
     return element; 
    }, 
    renderList: function(state, listElement, itemDataAttr) { 
     var itemsHTML = state.items.map(
      function(item, index) { 
       //what determines the index here? 
       console.log("index: " + index) 
       return renderItem(item, index, listItemTemplate, itemDataAttr); 
      }); 
      listElement.html(itemsHTML); 
    } 
} 

// event listeners 

var eventHelper = { 
    handleItemAdds: function(formElement, newItemIdentifier, itemDataAttr, listElement, state) { 
     formElement.submit(function(event) { 
      event.preventDefault(); 
      var newItem = formElement.find(newItemIdentifier).val(); 
      console.log(newItem) 
      stateHelper.addItem(state, newItem); 
      console.log(newItemIdentifier) 
      this.reset(); 
     }); 
    }, 
    handleItemDeletes: function(formElement, removeIdentifier, itemDataAttr, listElement, state) { 
     listElement.on('click', removeIdentifier, function(event) { 
      var itemIndex = parseInt($(this).closest('li').attr(itemDataAttr)); 
      console.log("this: " + this); 
      console.log("$(this).closest('li').attr(itemDataAttr " + $(this).closest('li').attr(itemDataAttr)); 
      stateHelper.deleteItem(state, itemIndex); 
      renderList(state, listElement, itemDataAttr); 
      console.log("what is itemDataAttr? it is: " + itemDataAttr) 
     }) 
    }, 
    handleItemToggles: function(listElement, toggleIdentifier, itemDataAttr, state) { 
     listElement.on('click', toggleIdentifier, function(event) { 
      var itemId = $(event.currentTarget.closest('li')).attr(itemDataAttr); 
      var oldItem = stateHelper.getItem(state, itemId); 

      stateHelper.updateItem(state, itemId, { 
       displayName: oldItem.displayName, 
       checkedOff: !oldItem.checkedOff 
      }); 
      renderHelper.renderList(state, listElement, itemDataAttr) 
     }); 
    } 
} 


$(function() { 
    var formElement = $('#js-shopping-list-form'); 
    var listElement = $('.js-shopping-list'); 

    //id of input containing list items 
    var newItemIdentifier = "#js-new-item"; 

    //in listItemTemplate above; the delete button has this class 
    var removeIdentifier = ".js-shopping-item-delete"; 

    //stores id of list item 
    var itemDataAttr = "data-list-item-id"; 

    var toggleIdentifier = ".js-shopping-list-toggle" 

    eventHelper.handleItemAdds(formElement, newItemIdentifier, itemDataAttr, listElement, state); 
    eventHelper.handleItemDeletes(formElement, removeIdentifier, itemDataAttr, listElement, state); 
    eventHelper.handleItemToggles(listElement, toggleIdentifier, itemDataAttr, state); 
}); 

Und hier ist die index.html Referenz:

<!DOCTYPE html> 
<html lang="en"> 
<head> 
    <title>Shopping List</title> 

    <link rel="stylesheet" href="https://cdnjs.cloudflare.com/ajax/libs/normalize/4.2.0/normalize.min.css"> 
    <link href="https://fonts.googleapis.com/css?family=Roboto" rel="stylesheet"> 

    <link rel="stylesheet" href="main.css"> 
</head> 
<body> 

    <div class="container"> 
    <h1>Shopping List</h1> 

    <form id="js-shopping-list-form"> 
     <label for="shopping-list-entry">Add an item</label> 
     <input type="text" name="shopping-list-entry" id="shopping-list-entry" placeholder="e.g., broccoli"> 
     <button type="submit">Add item</button> 
    </form> 

    <ul class="shopping-list"> 
    </ul> 
    </div> 
    <script src="jquery-3.1.1.js"></script> 
    <script type="text/javascript" src="index.js"></script> 
</body> 
</html> 
+2

'newItemIdentifier' ist' # js-new-item', ich kann dieses Element in Ihrem Code nicht finden, vermisse ich etwas? –

+0

Fügen Sie dynamisch ein Element '# js-new-item' irgendwo hinzu? In der Zeile, die Ihren Fehler verursacht, suchen Sie nach dem Wert dieses Elements, aber ich sehe es nirgends in Ihrem HTML. Ich habe das JS nicht gründlich durchkämmt, aber ich habe keine Art von "append" oder "appendTo" gesehen, was mich glauben lässt, dass Sie versuchen, das "val()" eines Elements zu erhalten, das nicht existiert. ** EDIT: ** axel.michel schlag mich dazu: ^) – Santi

+0

Natürlich! Danke, ich habe vergessen, das zu aktualisieren. Ich schätze die Hilfe. – Alacritas

Antwort

0

Alacritas,

ich, dass Sie nicht überall in der Ansicht sehen haben tatsächlich ein Element mit einer ID, die mit diesem Accessor übereinstimmt (# js-new-item).

Ihr Kommentar sagt, dass es zu dem Eingabefeld gehört, aber das Eingabefeld, das Sie in Ihrem HTML haben, hat diese ID nicht.

Ich denke, Sie müssten die Zeichenfolge "# js-new-item" auf "# shopping-list-entry" aktualisieren.

+0

Perfekt! Genau das habe ich verpasst. – Alacritas

Verwandte Themen