为什么我在使用jQuery .val()分配的变量上未定义?

时间:2017-01-13 20:54:26

标签: javascript jquery

我制作了一个基本的购物清单应用程序并且遇到了问题。该程序默默地失败,并在检查断点等时,我发现在第75行,我将newItem定义为未定义。

正确定义了语句中的其他所有内容。我知道我做错了什么?

这里是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);
});

这里有index.html供参考:

<!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>

1 个答案:

答案 0 :(得分:0)

Alacritas,

我没有在您的视图中看到您实际上有一个ID与该访问者匹配的元素(#js-new-item)。

您的评论说它属于输入框,但您在html中的输入框没有该ID。

我认为你需要更新字符串&#34; #js-new-item&#34;将成为#shopping; list-entry&#34;。