使用MVC3中的AJAX从间隔时间检索控制器中的数据

时间:2012-08-31 14:47:17

标签: javascript jquery ajax asp.net-mvc-3 setinterval

对于我的公司,我们正在为发票系统构建一个Web应用程序,该系统使用类似于Facebook的通知栏,用户可以通过下拉菜单显示系统上的交易状态,同时总数未完成的交易显示在它旁边。请参阅图片了解详情。

http://img210.imageshack.us/img210/4379/alertdrop.png

我们正在使用下拉菜单中的表格代码检索此数据:

<table id="alertDropTable" style="margin-top:10px;">

    @{
        Dictionary<string, int> dic = ViewBag.statusCount;
        if (dic != null)
        {
            for (int i = 0; i < dic.Count; i++)
            {
                if (dic.Values.ElementAt(i) > 0)
                {
                    <tr>
                        <td width="100%" style="padding-bottom:4px; padding-top:4px; padding-left:10px; padding-right:10px; vertical-align:middle;">
                            You have <strong><a style="background-color:#878787; border-radius:5px; color:White; padding:3px;">@dic.Values.ElementAt(i)</a></strong> @dic.Keys.ElementAt(i) transaction(s).
                        </td>
                    </tr>
                }
            }
        }
    }

</table>

以下是跨度,显示总数:

<div style="float: left;">
    <a href="javascript:;" onmouseover="document.alert.src='@Url.Content("~/Content/images/alert_notification_hover.png")'" onmouseout="document.alert.src='@Url.Content("~/Content/images/alert_notification.png")'" onclick="toggle('notificationDrop');"><img src="@Url.Content("~/Content/images/alert_notification.png")" name="alert" alt="alert"/></a>

            @{
                Dictionary<string, int> dicheader = ViewBag.statusCount;
                int diccount = 0;
                if (dicheader != null)
                {
                    for (int i = 0; i < dicheader.Count; i++)
                    {
                        if (dicheader.Values.ElementAt(i) > 0)
                        {
                            diccount = diccount + @dicheader.Values.ElementAt(i);
                        }
                    }
                }
            }

    </div>

    <div id="alertTotalDiv" style="float:left;margin-top:6px; margin-left:5px;"><span id="alertTotal" style="vertical-align:middle; background-color:#878787; border-radius:5px; color:White; font-family:Georgia; font-size:20px; padding:3px; padding-left:5px; padding-right:5px;margin-top:0px;">@diccount</span></div>

此代码目前存储在全局“_layout.cshtml”文件中。请原谅代码的粗糙,这是一个非常早期的版本。但是,这在检索页面加载数据方面工作正常。但是,系统要求每隔几秒自动更新此信息,而不刷新整个页面。本质上,调用控制器以恢复当前数据并使用当前值更新<table><span>

我被要求创建一个Ajax函数,该函数从“AlertController”中检索数据并相应地更新视图。请在下面找到该控制器的内容:

public class AlertController : Controller
{

    /// <summary>
    /// Gets or sets the user service contract.
    /// </summary>
    /// <value>The user service contract.</value>
    public IUserServiceContract UserServiceContract { get; set; }

    /// <summary>
    /// Initializes a new instance of the <see cref="BaseController"/> class.
    /// </summary>
    protected AlertController()
    {
        this.UserServiceContract = Gateway.Instance.Resolve<IUserServiceContract>();

    }

    /// <summary>
    /// Get the AlertTypes
    /// </summary>
    /// <returns></returns>
    public virtual void ViewAlerts()
    {
        Gateway.Instance.Logger.LogInfo(string.Format("Overview Controller View:    Fetching list of alerts."));

        try
        {
            if (this.UserServiceContract != null)
            {
                var allAnnouncements = this.UserServiceContract.GetAnnoucements();
                var userAlertSettings = this.UserServiceContract.GetUserAlert();


                ViewBag.statusCount = userAlertSettings;
                ViewBag.announcements = allAnnouncements.ToList();
            }
        }
        catch (Exception ex)
        {
            Gateway.Instance.Logger.LogInfo(ex);
            throw new Exception(string.Format("Home Controller View Error:  {0} occured while fetching alerts.", ex.Message), ex);
        }
    }

我很难过,但是已经给出了以下Ajax函数示例,它用于完全执行不同的任务,以帮助我:

$.ajax({
    url: '@Url.Action("ViewAlerts", "Alerts")',
    data: { ownerIds: ownerIds },
    traditional: true,
    dataType: 'json',
    success: function (result) {
        for (i = 0; i < ownerIds.length; i++) {
            $(".ownersTable tr[id='tablerow+" + ownerIds[i] + "']").remove();
        }
    },
    error: function (xhr, ajaxOptions, thrownError) {
        $("#confirmDiv").alertModal({
            heading: '@Language.Fail',
            body: '@Language.AlertRemoveOwnerFailed' + thrownError
        });
    }
});

到目前为止,我唯一能设法工作的是设定间隔功能,每隔5秒发出一次警报!

对此有何指导?

3 个答案:

答案 0 :(得分:1)

好的,这是你需要做的,首先是:

$.ajax({
    url: '@Url.Action("ViewAlerts", "Alerts")', 
    data: { ownerIds: ownerIds },
    traditional: true,
    dataType: 'json',
    success: function (result) {
        for (i = 0; i < ownerIds.length; i++) {
            $(".ownersTable tr[id='tablerow+" + ownerIds[i] + "']").remove();
        }
    },
    error: function (xhr, ajaxOptions, thrownError) {
        $("#confirmDiv").alertModal({
            heading: '@Language.Fail',
            body: '@Language.AlertRemoveOwnerFailed' + thrownError
        });
    }
});

为什么Url.Action在引号中?只是把@ Url.Action ...我没有看到引号的原因,它可能会打破你的电话。

其次不要使用ViewBag。它不应该被用来保存'数据'(在我看来)。你应该使用一个模型。所以这就是你能做的:

将要更新的页面部分创建为“部分视图”,该部分视图强烈类型化为包含状态和公告以及您需要的任何其他内容的模型。

使用Jquery“加载”将获取数据并返回此“部分视图”的Controller方法,并将其加载到屏幕上的Div示例中:

$('#div-to-load-into').load('/myactionurl/', function () { //Do something when done });

然后调用您的控制器,获取数据并返回您创建的模型的局部视图!

祝你好运!

---编辑---你应该在上面做,因为它会更容易和更快(如果你做重新设计,你会很快理解,但这里有一个如何做你想要的想法)

这是你需要知道的,

url 是Ajax要调用的操作。你需要把url:'/ controller / action'

数据是您要发送给该操作的数据{parameter-name:parameter}在您的情况下,您发送的数据看起来不像是因为您只刷新了一次,所以您不需要需要包括这个

dataType 是您希望返回的数据,可能是“html”或“json”,在您的情况下,由于您使用的是“ViewBag”而无法返回任何内容

如果成功调用ajax调用并且在'result'中没有错误,则会调用成功,在您没有结果的情况下,因为您使用了视图包。

现在我不能保证这会有效,因为我从未尝试过:

function(result)
{
var updated_values = @Html.Raw(Json.Encode(ViewBag.AlertStatus)) 
}

在ajax的成功函数内试试这个,这可能会也可能不会起作用。老实说,我不知道ViewBag是否会有更新的值。此时,您只需要用新值替换表值!你将不得不在javascript中做所有这些,我建议查看Jquery中的'appendTo','replaceWith','html'等函数来弄清楚如何做到这一点。

$.ajax({
    url: 'controller/action', 
    success: function (result) {
        var alert_info = @Html.Raw(Json.Encode(ViewBag.AlertStatus)) 
    },
    error: function (xhr, ajaxOptions, thrownError) {
        //error handling
    }
});

答案 1 :(得分:0)

(function checkStatus() {
  $.ajax({
    url: '@Url.Action("ViewAlerts", "Alerts")', 
    data: { ownerIds: ownerIds },     
    traditional: true,     
    dataType: 'json',
    success: function (result) 
    {         
      for (i = 0; i < ownerIds.length; i++) 
       {             
         $(".ownersTable tr[id='tablerow+" + ownerIds[i] + "']").remove();
       }     
    },
    complete: function() {
      // Schedule the next request when the current one's complete
      setTimeout(checkStatus, 5000);
    }
  });
})();

How to fire AJAX request Periodically?

答案 2 :(得分:0)

为了将操作中的数据提供给JavaScript,您的操作必须返回数据。现在,您的“操作”实际上不是一个操作,因为它返回void并设置ViewBag属性,这些属性无法从JavaScript访问。所以你的行动需要更像是:

[HttpGet]
public ActionResult Alerts()
{
    IEnumerable alerts;
    // ...code which gets data into alerts
    return JsonResult(alerts);
}

显然我不知道你的域名,所以我不知道你将如何构建回来的数据,但基础知识就在那里。 $.ajax调用将指向操作路由(在这种情况下,可能是'/Alert/Alerts')。 success函数将具有data参数以及相应的对象数组。从那里你用数据更新你的DOM。