3

我在注销后遇到问题,我重定向到我网站的登录页面。但是,除非我刷新,否则登录页面的 javascript 根本不会执行。

我正在使用以下链接调用 Account 控制器的 LogOff 操作(此代码位于单独的控制器中):

@Html.ActionLink("Logout", "LogOff", "Account", null, new { data_icon = "gear", @class = "ui-btn-right" })

Account 控制器中的 LogOff 方法如下所示,其中我传递了一个注销参数,以便在登录视图中检测我从注销操作来到这里:

public ActionResult LogOff()
{
    return Redirect(Url.Action("LogOn", "Account", new RouteValueDictionary(new { logout = true })));
}

检查萤火虫,我注意到javascript

$(document).ready(function () { ... });

在我的登录页面中使用的根本不执行。

此外,登录页面的 url 显示为“localhost:#####/Account/LogOff”,而不是我预期的“localhost:#####/Account/LogOn?logout=True”。

如果我之后尝试提交登录表单,那么我将被发送到一个空白页面,其 url 为“http://localhost:#####/?logout=True”

所以我想知道我做错了什么导致页面无法加载其javascript,以及如何解决这个问题。

谢谢!

更新: 这是我的登录控制器方法:

public ActionResult LogOn()
{
    List<SelectListItem> cpList = new List<SelectListItem>();

    // Retrieve the list of central points from web.config
    NameValueCollection centralPoints = (NameValueCollection)ConfigurationManager.GetSection("CentralPointDictionary");

    foreach (string cp in centralPoints)
        cpList.Add(new SelectListItem { Text = cp as string, Value = centralPoints[cp] as string });

    // Check for a cookie containing a previously used central point
    string selectedCP = string.Empty;
    if (ControllerContext.HttpContext.Request.Cookies["LastCentralPoint"] != null)
        selectedCP = ControllerContext.HttpContext.Request.Cookies["LastCentralPoint"].Value;
    else if (cpList.Count > 0)
        selectedCP = cpList[0].Text;
    LogOnModel loginModel = new LogOnModel { CentralPointsList = new SelectList(cpList, "Value", "Text", selectedCP) };
    return View(loginModel);
}

我的观点的主体:

<div data-role="page" id="page">
    <div data-role="header" data-position="inline">
        <div id="languageContainer" data-role="fieldcontain">
        <select id="languageSelect" data-mini="true" data-theme="b" data-overlay-theme="d" data-native-menu="false" data-inline="true">
            <option value="English">English</option>
            <option value="Français">Français</option>
        </select>
        </div>
    </div><!-- /header -->

    <div data-role="content" id="contentFrame" class="frame">
        <div id="controlFrame">
            @using (Html.BeginForm())
            {
            <div id="centralPoint" class="frame">
                    @Html.DropDownListFor(model => model.CentralPointAddress, Model.CentralPointsList, new { id = "centralPointSelect", name = "centralPoint", data_mini = "true", data_inline = "true", data_native_menu = "false" })
            </div>
                <div id="errorMsg">@Html.ValidationSummary()</div>
            <div id="credentialsFrame" class="frame">
                @Html.TextBoxFor(m => m.UserName, new { id = "userField", type = "text", name = "Username" })
                @Html.PasswordFor(m => m.Password, new { id = "passField", type = "password", name = "Password" }) 
            </div>
            <input id="loginBtn" type="submit" value="Login" />
            <div id="rememberMe" class="frame">
                        @Html.CheckBoxFor(m => m.RememberMe, new { @class = "custom", data_mini = "true" })
                        @Html.LabelFor(m => m.RememberMe)
            </div>
            <div id="forgotPassFrame">
                <input id="forgotPass" type="button" data-mini="true" value="Forgot password?" />
            </div>
            @Html.HiddenFor(m => m.Encrypted, new { id = "encrypted", value = "false" })
            }
        </div>
        @using (Html.BeginForm("SuccessfulLogin", "Account", FormMethod.Get, new { id = "successForm" }))
        {
            <input id="returnUrl" name="returnUrl" type="hidden" />
        }
    </div><!-- /content -->
 </div><!-- /page -->
4

2 回答 2

3

事实上,这个问题与 jQuery Mobile 有关。来自 JQM 文档:http: //jquerymobile.com/test/docs/api/events.html

在 jQuery 中学习的第一件事是调用 $(document).ready() 函数中的代码,以便在加载 DOM 后立即执行所有内容。但是,在 jQuery Mobile 中,Ajax 用于在您导航时将每个页面的内容加载到 DOM 中,并且 DOM 就绪处理程序仅针对第一页执行。要在加载和创建新页面时执行代码,您可以绑定到 pageinit 事件。此事件在本页底部有详细说明。

仅对我来说,“pageinit”不起作用,但“pagechange”成功了。

所以我最终要做的是:从 $(document).ready() 中提取我的原始代码并将其插入到一个单独的函数中。现在看起来像这样:

$(document).ready(DocumentReady);

$(document).bind("pagechange", function () {
    // check if we just logged out to ensure we don't call DocumentReady() 
    // twice in succession
    if (window.location.href.indexOf("LogOff") > -1) {
        DocumentReady();
    }
});

function DocumentReady() {
    // some initialization code
});

然而...

这解决了我的 javscript 没有执行的第一个问题,但是我的 UI 没有显示 javascript 所做的更改。

正如 JQM 文档所述,整个应用程序在单个文档中运行。所以我的 LogOff 控制器方法(重定向到 LogOn)导致一个新的登录页面被注入(或附加)到现有页面中。然后,当我的 javascript 代码使用 访问文本输入字段时$("#userField"),它是从在应用程序一开始加载的页面访问该字段,而不是在注销后显示的那个!

我后来发现,通过为 window.location 赋值来更改页面位置会导致完全刷新。因此,在注销时,我可以这样做,而不是调用控制器方法:

$("#logoutBtn").click(function () {
    window.location = $.mobile.path.parseUrl(window.location.href).domain + "/Account/LogOn";
});

由于这会导致页面完全刷新,$(document).ready() 事件被触发,这意味着我之前所说的关于绑定到“pagechange”或“pageinit”的内容不再需要,尽管仍然很好了解使用 jQuery 移动时。刷新还加载了一个全新的 DOM,因此我可以确定我的 javascript 会影响页面上显示的元素。

于 2012-06-26T14:51:59.093 回答
0

使用RedirectToAction()而不是redirect().

于 2012-06-22T19:59:19.093 回答