0

对于我的公司,我们正在为一个发票系统构建一个 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 秒发出一次警报!

对此有何指导?

4

3 回答 3

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'

data是您发送给该操作的数据 { parameter-name: parameter } 在您的情况下,您似乎没有发送数据,因为您只轮询刷新,因此您不需要包含此

dataType是您期望返回的数据,它可以是 'html' 或 'json' ,在你的情况下你什么都不返回,因为你使用了 'ViewBag'

如果成功调用了 ajax 调用并且没有错误,则成功将被调用,结果在“结果”中,在你的情况下你没有结果,因为你使用了视图包。

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

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
    }
});
于 2012-08-31T15:03:11.267 回答
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);
    }
  });
})();

如何定期触发 AJAX 请求?

于 2012-08-31T15:04:10.000 回答
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。

于 2012-08-31T16:46:22.310 回答