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>
'newItemIdentifier' ist' # js-new-item', ich kann dieses Element in Ihrem Code nicht finden, vermisse ich etwas? –
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
Natürlich! Danke, ich habe vergessen, das zu aktualisieren. Ich schätze die Hilfe. – Alacritas