JavaScript运行时错误:无法获取未定义或空引用的属性'forEach'

5
我有一个aspx母版页应用程序,在子aspx页面的asp:content部分中有两个下拉列表控件。其中一个控件从SQL数据库中填充。另一个控件基于从第一个下拉列表中选择的项目进行填充。我正在尝试在我的代码中使用这个解决方案,但是我遇到了一个错误:

JavaScript运行时错误:无法获取未定义或空引用的属性'forEach'

如何根据所选的州来显示城市名称?
我的代码块是:

  <link rel="stylesheet" href="//code.jquery.com/ui/1.11.1/themes/smoothness/jquery-ui.css">
  <script src="//code.jquery.com/jquery-1.10.2.js"></script>
  <script src="//code.jquery.com/ui/1.11.1/jquery-ui.js"></script>

    <script type="text/javascript">
        AL = new Array('Birmingham', 'Montgomery', 'Tuscaloosa');
        FL = new Array('Miami', 'FtLauderdale', 'Jacksonville');
        GA = new Array('Atlanta', 'Macon', 'Athens');

        populateSelect();

        $(function () {

            $('#ddlState').change(function () {
                populateSelect();
            });

        });

        function populateSelect() {
            category = $('#ddlState').val();
            $('#ddlCity').html('');

            eval(category).forEach(function (t) {
                $('#ddlCity').append('<option>' + t + '</option>');
            });
        }
    </script>  

<asp:DropDownList ID="ddlCity" runat="server" CssClass="stdFldWidth" onchange="setFDFlag()">
</asp:DropDownList>    

<asp:DropDownList ID="ddlState" runat="server" CssClass="stdFldWidth" DataSourceID="dsUSState"
    DataTextField="US_State" DataValueField="State_ID" AutoPostBack="true" > 
</asp:DropDownList>  

更新:
Protected Sub ddlState_SelectedIndexChanged(sender As Object, e As System.EventArgs) Handles ddlType.SelectedIndexChanged
If ddlState.SelectedValue = "FL" Then
    DisplayRegulation(FL)
End If

永远不要使用eval()。如果你需要使用它,那么你的代码肯定有问题。 - emerson.marini
此外,当您在浏览器中检查下拉列表时,请检查它们的ID是否已更改。这是在使用ASP.NET时很常见的事情。 - emerson.marini
所以你的jQuery选择器不会将它们选中,因为它们是这样的。你可以给它们一个独特的类并使用它来代替ID。 - emerson.marini
你的回答和 @sebnukem 的协作已经达到了80%的效果。如果你能把它放回去,那会对我很有帮助。 - user3929962
我已经恢复了我的回答。 - emerson.marini
显示剩余2条评论
2个回答

3
常见问题是使用Master Pages的ASP.NET页面,生成的页面元素ID会发生变化。解决方案是为这些元素指定唯一的类,并在选择器中使用该类而非它们的ID:
<asp:DropDownList ID="ddlCity" runat="server" CssClass="stdFldWidth ddlCity" onchange="setFDFlag()">
</asp:DropDownList>    

<asp:DropDownList ID="ddlState" runat="server" CssClass="stdFldWidth ddlState" DataSourceID="dsUSState"
    DataTextField="US_State" DataValueField="State_ID" AutoPostBack="true" > 
</asp:DropDownList>

...

$(function () {
    var states = {
        AL: ['Birmingham', 'Montgomery', 'Tuscaloosa'],
        FL: ['Miami', 'FtLauderdale', 'Jacksonville'],
        GA: ['Atlanta', 'Macon', 'Athens']
    };

    function populateSelect() {
        $('.ddlCity').empty();

        var stateSelected = $('.ddlState').val();

        if (stateSelected) {
            states[stateSelected].forEach(function (sel) {
                $('<option>').val(sel).text(sel).appendTo($('.ddlCity'));
            });
        }
    }

    populateSelect();

    $('.ddlState').on('change', function() { 
        populateSelect();

        return true;
    });
});

使用@sebnukem的建议对数据进行对象化修改,因此可以摆脱eval()。
将整个代码置于jQuery文档准备就绪事件处理程序内进行更新。
在jQuery onchange事件处理程序中返回true,以便继续PostBack。
演示请见此处

@MelanciaUK 我不明白你的意思 - user3929962
哪一部分?我已更新答案,现在将所有Javascript/jQuery代码放在文档就绪事件处理程序中 - $(function () { });。而且我不认为您的代码后台存在可能会破坏此代码的问题 - 导致您问题中所述的Javascript错误。 - emerson.marini
1
啊,对了。我忘记添加调用 populateSelect() 的代码了。请再试一下更新后的答案(刚刚编辑过)。 - emerson.marini
可能是这样。尝试调试代码后端和客户端,逐步查看发生了什么。 - emerson.marini
好的,当我将AutoPostBack设置为false时,一切都运行得非常完美。但是当我将其设置回true时,我遇到了我上一个评论中提到的问题。 - user3929962
显示剩余9条评论

2
永远不要使用 eval。相反,应该将数据存储在对象中:
var states = {
    'AL': ['Birmingham', 'Montgomery', 'Tuscaloosa'],
    'FL': ['Miami', 'FtLauderdale', 'Jacksonville'],
    'GA': ['Atlanta', 'Macon', 'Athens']
};

function populateSelect() {
    var category = $('#ddlState').val(); // selected state

    if (category && states[category]) {
        $('#ddlCity').html('');
        states[category].forEach(function (t) {
            $('#ddlCity').append('<option>' + t + '</option>');
        });
    } else {
        console.log('invalid state input: '+category); 
    }
}

$(function () {
    $('#ddlState').change(function () {
        populateSelect();
    });
    populateSelect();
});

我假设<asp:DropDownList>元素会生成一个指定ID的HTML元素。

那就意味着category的值在states对象中找不到匹配的键。使用console.log('state = '+ category);语句检查您的值。 - sebnukem

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接