为什么我用jQuery Mobile和Razor获得这个Javascript HIERARCHY_REQUEST_ERR?

时间:2012-04-06 06:52:49

标签: asp.net-mvc jquery-mobile razor

在这里迷茫和困惑......有问题的字段是一个布尔值,我想要UI是一个复选框(或者是/否或开/关jQuery滑块)。每次我尝试添加此复选框输入时,我最终得到一个

Microsoft JScript runtime error: DOM Exception: HIERARCHY_REQUEST_ERR (3)

错误。

这是HTML + Razor

 <div data-role="fieldcontain">
    <fieldset data-role="controlgroup">
       <legend>End Game:</legend>
       @Html.TextBoxFor(model => model.HandicapSession.WinByTwo, new { @type="checkbox" })
       <label for="WinByTwo">Win By Two?</label>
    </fieldset>
</div>

这是生成的HTML:

<div data-role="fieldcontain">
    <fieldset data-role="controlgroup">
       <legend>End Game:</legend>
       <input data-val="true" data-val-required="The WinByTwo field is required." id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" type="checkbox" value="False" />
       <label for="WinByTwo">Win By Two?</label>
    </fieldset>
</div>

当jQuery Mobile创建其复选框小部件时,如果存在冲突或重叠的ID,则会发生此错误

$.widget( "mobile.checkboxradio", $.mobile.widget, { ...etc...

但是如何使用HTML和/或razor在jQuery Mobile中制作一个简单的复选框呢?

2 个答案:

答案 0 :(得分:2)

如果jQuery Mobile的问题确实是HTML标记的重复名称,那么您必须在HTML中呈现自己的input type=checkbox标记,因为ASP.NET MVC Html.CheckBoxFor帮助方法将呈现具有重复名称值的input type=hidden标记。有关讨论,请参阅this post

隐藏的表单标记就在那里,因为如果您向服务器提交未选中的复选框,则不包括该字段的表单值。因此input中包含隐藏的value=false标记,因此如果取消选中该复选框,则仍会提交值false。 MVC中的模型绑定过程将为您过滤掉重复的表单值,但如果您遇到重复名称属性的客户端问题,则必须在HTML中呈现自己的复选框和标签,然后处理事实上,当取消选中该框时,不会为HandicapSession.WinByTwo属性提交任何值。如果没有提交HandicapSession的其他属性,那么整个对象将为null。

因此,您可以手动创建复选框输入并仍然根据需要加载模型中的checkedvalue属性,但是您可能会遇到模型绑定问题,其中WinByTwo的值仍然存在即使选中此框也是假的。

另请注意,for上的label属性与示例中的复选框ID不匹配。您需要完整的HandicapSession_WinByTwo

以下手动创建输入标记:

<link rel="stylesheet"  href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />  
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>

<div data-role="page">
    <div data-role="content"> 
        <div data-role="fieldcontain">
            <fieldset data-role="controlgroup">
               <legend>End Game:</legend>
               <input type="checkbox" id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" @(Model.HandicapSession.WinByTwo ? "checked=checked" : "") value="@(Model.HandicapSession.WinByTwo.ToString().ToLower())" />
               <label for="HandicapSession_WinByTwo">Win By Two?</label>
            </fieldset>
        </div>
    </div>
</div> 

对于加载时选中的复选框,HTML输出如下:

<div data-role="page">
    <div data-role="content"> 
        <div data-role="fieldcontain">
            <fieldset data-role="controlgroup">
               <legend>End Game:</legend>
               <input type="checkbox" id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" checked=checked value="true" />
               <label for="HandicapSession_WinByTwo">Win By Two?</label>
            </fieldset>
        </div>
    </div>
</div>

最好的只是使用MVC辅助方法,所以我不确定你是否尝试过以下方法。默认的Html.CheckBoxForHtml.LabelFor辅助方法适用于jQuery Mobile 1.0a4.1或1.1.0。以下适用于我:

<link rel="stylesheet"  href="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.css" />  
<script type="text/javascript" src="http://code.jquery.com/mobile/1.0a4.1/jquery.mobile-1.0a4.1.min.js"></script>

<div data-role="page">
    <div data-role="content"> 
        @using (Html.BeginForm())
        { 
            <div data-role="fieldcontain">
                <fieldset data-role="controlgroup">
                   <legend>End Game:</legend>
                   @Html.CheckBoxFor(m => m.HandicapSession.WinByTwo)
                   @Html.LabelFor(m => m.HandicapSession.WinByTwo, "Win By Two?")

                   <input type="submit" id="SubmitForm" value="submit" />
                </fieldset>
            </div>
        }
    </div>
</div>

这会产生HTML输出:

<div data-role="page">
    <div data-role="content"> 
        <form action="/Mobile/Mobile" method="post">            
             <div data-role="fieldcontain">
                <fieldset data-role="controlgroup">
                   <legend>End Game:</legend>

                   <input checked="checked" data-val="true" data-val-required="The WinByTwo field is required." id="HandicapSession_WinByTwo" name="HandicapSession.WinByTwo" type="checkbox" value="true" />
                   <input name="HandicapSession.WinByTwo" type="hidden" value="false" />
                   <label for="HandicapSession_WinByTwo">Win By Two?</label>

                   <input type="submit" id="SubmitForm" value="submit" />
                </fieldset>
            </div>
        </form>    
    </div>
</div> 

答案 1 :(得分:0)

修复可能非常简单。

选择1 :去焦土,关闭基于Ajax的导航。这将确保唯一ID保持唯一。这将确保您再也不会遇到此问题。唯一的缺点是你会丢失页面之间相当小的转换(有人称之为whambulance )。您可以通过设置global configuration script ...

来完成此操作
script src="jquery.js"
script src="custom-scripting.js"
script src="jquery-mobile.js"

在里面,你将覆盖ajax设置以禁用它们......

$(document).bind("mobileinit", function(){
    $.mobile.ajaxEnabled = false;
});

选择2:使用属性为rel='external'target='_black'的链接调用需要此唯一性的页面,这将完成相同的操作而不会禁用所有内容基于ajax的导航。如果您作为表单帖子的结果访问该页面,则可以使用表单标记上的data-ajax='false'来完成清理加载。