在另一个

时间:2017-03-17 18:10:06

标签: javascript c# jquery asp.net-mvc

我有一个脚本在加载数据后渲染部分视图,但我希望至少有一个其他部分视图使用相同的数据加载。这是一个长时间运行的查询(30秒 - 1分钟),因此我不想为每个局部视图加载它。还是我走错了路?应该注意的是,我对ASP.Net还是一个新手,对Javascript / Jquery来说还是一个新手,所以我并不完全了解最佳实践,所以如果你发现一些“违反惯例”,请告诉我,太。

编辑:我突然意识到我应该注意到我最终想要达到的目标。在我当前的非ASP应用程序(C#/ XAML)中,它在应用程序加载时加载数据(下面使用等效的LoadMonitorData方法),然后每15分钟刷新一次。或者刷新按钮可以触发刷新。

这是我到目前为止所得到的......任何帮助或指导都将不胜感激。

Index.cshtml

@{
    ViewBag.Title = "MMCView";
}

@section scripts {
    <script type="text/javascript">
        $(document).on('click', '[name^=project]', function () {
            if ($(this).hasClass('selected')) {
                $('.mig-project').removeClass('selected').removeClass('low-opacity').addClass('full-opacity');
                $('#data-area').removeClass('show-data-view');
            }
            else {
                $(this).addClass("selected").addClass('full-opacity').removeClass('low-opacity');
                $('.mig-project').not(this).removeClass("full-opacity").removeClass('selected').addClass("low-opacity");
                $('#data-area').load($(this).data("url"));
                $('#data-area').addClass('show-data-view');
            }
        })
    </script>

    <script type="text/javascript">
        $(document).ready(function(e) {
            $("#list-container").each(function(index, item) {
                var url = $(item).data("url");
                if (url && url.length > 0) {
                    $(item).load(url);
                }
            })
        })
    </script>
}

<div class="project-list slow-load" id="list-container" data-url="/mmc/projectpanes">
    <img src="loading.gif" />
</div>

<div class="hide-data-view slow-load" id="data-area" data-url="/mmc/projectdata"></div>

MMCController.cs

using MMC_ASP.Models;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Http;
using System.Text;
using System.Threading.Tasks;
using System.Web.Mvc;
using System.Web.Script.Serialization;

namespace MMC_ASP.Controllers
{
    public class MMCController : AsyncController
    {
        MonitorData downloadedInfo = new MonitorData();

        //GET: MMC
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult ProjectPanes()
        {
            downloadedInfo = LoadMonitorData();
            return PartialView("_ProjectPanes", downloadedInfo.MainPanel.OrderBy(o => o.Client).ToList());
        }

        public ActionResult ProjectData(string server)
        {
            return PartialView("_ProjectData", downloadedInfo.Information.Where(x => x.ServerName == server).ToList());
        }

        public ActionResult MainWindowMonitor()
        {
            return PartialView("_MainWindowMonitor", downloadedInfo.MonitorText);
        }

        public MonitorData LoadMonitorData()
        {
            MonitorData deserializedData = null;
            using (WebClient wc = new WebClient())
            {
                wc.Encoding = Encoding.Unicode;
                string location = "http://MYWEBAPI-RETURNS-JSON";
                string data = wc.DownloadString(new System.Uri(location));
                var deserializer = new JavaScriptSerializer();
                deserializedData = deserializer.Deserialize<MonitorData>(data);
            }
            return deserializedData;
        }
    }
}

2 个答案:

答案 0 :(得分:1)

在这种情况下,Cache对象可能对您有用。您可以将数据存储在缓存中,将其设置为在一段合理的时间后过期,编写辅助函数以在缓存数据过期时动态重新提取数据,并使您的部分视图从数据库中提取数据辅助功能。这样,新数据只会根据需要被拉出,无论有多少视图使用它,作为奖励,您可以轻松控制重新执行该昂贵查询的频率。

请注意,这在您的情况下效果很好,因为您的数据本质上是全局的。如果您将特定于用户的参数传递到查询中,那么缓存就不适合。

using System.Web.Caching;

private MonitorData getCachedData()
{
  var cache = this.HttpContext.Cache;

  if (cache["MonitorData"] == null)
    cache.Add("MonitorData", LoadMonitorData(), null, DateTime.Now.AddMinutes(15), Cache.NoSlidingExpiration, CacheItemPriority.Normal, null); // 15 minute cache expiration, as example
  return (MonitorData)cache["MonitorData"];
}

public ActionResult ProjectPanes()
{
    downloadedInfo = getCachedData();
    return PartialView("_ProjectPanes", downloadedInfo.MainPanel.OrderBy(o => o.Client).ToList());
}

public ActionResult ProjectData(string server)
{
    downloadedInfo = getCachedData();
    return PartialView("_ProjectData", downloadedInfo.Information.Where(x => x.ServerName == server).ToList());
}

public ActionResult MainWindowMonitor()
{
    downloadedInfo = getCachedData();
    return PartialView("_MainWindowMonitor", downloadedInfo.MonitorText);
}

答案 1 :(得分:0)

Joe_Irby提出的解决方案非常有效!然而,在与他沟通时,我发现另一种方法也可行。我想我会把它包含在这里,所以任何寻找解决方案的人都可以决定哪一个最适合他们的情况。

https://code.msdn.microsoft.com/Caching-In-Web-API-cb40be30