无需刷新页面即可更新数据库调用

6
用户将看到一组图片(宝藏),从中选择一张并存储到Learner_treauser表中。
List<The_Factory_Chante.Models.Treasure> tresh;

using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{

    string imageSource = "";

    tresh = db2.Treasures.ToList();

    foreach (var item in tresh)
    {
        if (item.itemImage != null)
        {
            string imageBase = Convert.ToBase64String(item.itemImage);
            imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
        }

        <img id="@item.treasureID" src="@imageSource" onclick="return MakeSure(@item.treasureID)" />
    }
}

当选择一张图片时,会调用该函数。在此函数中,将图片发送到一个Web服务方法以保存到数据库,并重新加载页面以进行更新:
function MakeSure(treshID) {

    var id = treshID
    $.ajax({
        url: "../../WebService.asmx/MakeSure",
        data: "{ 'id': '" + id + "'}",
        dataType: "json",
        type: "POST",
        contentType: "application/json; charset=utf-8",
        success: function (data) {
        },
        error: function (XMLHttpRequest, textStatus, errorThrown) {
        }

    });
    window.location.reload();
};

但这对用户来说并不是很愉悦的体验。更好的方式是在不刷新页面的情况下更新内容。
以下是接收所选图像ID并将其存储在"Learner_Treasure"表中的"Webservice"方法。
public void MakeSure(int id)
{
   using (The_FactoryDBContext db = new The_FactoryDBContext())
   {
       Learner_Treasure learnTreasure = new Learner_Treasure();

       learnTreasure.dateCompleted = DateTime.Today;
       learnTreasure.learnerID = UserInfo.ID;
       learnTreasure.treasureID = id;

       db.Learner_Treasure.Add(learnTreasure);
       db.SaveChanges();

   }

调用Learner_Treasure表格的代码。

List<The_Factory_Chante.Models.Learner_Treasure> lern;
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{

    string imageSource = "";
    lern = db2.Learner_Treasure.ToList();
    if (lern != null)
    {
        foreach (var item in lern)
        {
            if (item.learnerID == UserInfo.ID)
            {
                byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
                string imageBase = Convert.ToBase64String(bytes);
                imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
                <img id="@item.treasureID" src="@imageSource"/>
            }
        }

这段代码将向用户显示他们选择的所有图像,但是如果我删除 window.location.reload(); ,则该代码只有在页面重新加载时才会更新。这意味着用户在选择图片后无法立即看到所选的图片。
我想要做的是在不刷新页面的情况下更新调用 Learner_Table 的代码。

6
你有什么问题? - David Tansey
如果您不想刷新页面,请删除 window.location.reload();。在ajax成功回调中,您想要做什么并不清楚 - 您返回数据但从未对其进行任何操作。 - user3559349
你的问题不够清晰,而且你已经有了JavaScript中的更新函数。只需在“success”回调函数内更改您需要更改的内容即可。 - Andre Calil
@LuluthoMgwali,你的方法还不完整。在MakeSure之后会发生什么?基本上,你需要返回一些东西给你的JavaScript函数,并相应地更新页面。然而,通过你的代码很难得到一个完整的图片。 - Andre Calil
@AndreCalil 我已经添加了缺失的方法。 - Lulutho Mgwali
5个回答

2

有另一种方法来解决这个问题,你可以使用SignalR库。

以下是需要执行的步骤:

视图

// Include the SignalR Script
<script src="~/Scripts/jquery.signalR-2.2.0.js"></script>

// Provide a dynamic proxy for SignalR
<script src="~/signalr/hubs"></script>

// Define hub connection(see below)
var hub = $.connection.yourHub;

// This is what the Hub will call (Clients.All.getImage(imageSource);)
hub.client.getImage = function (img) {
    var image = '<img id="' + img.treasureId + '" src="data:image/jpg;base64,' + img.image + '"';
    $(image).appendTo("body");
};

// Start the connection to the hub
// Once we have a connection then call the getLearnerTreasureItem on the Hub
$.connection.hub.start().done(function () {
    var id = // whatever
    hub.server.getLearnerTreasureItem(id);
};

集线器

public class YourHub : Hub
{

    public void GetLearnerTreasureItem()
    {
        // All your code
        List<The_Factory_Chante.Models.Learner_Treasure> lern;
        using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
        {

         string imageSource = "";
         lern = db2.Learner_Treasure.ToList();
         if (lern != null)
         {
           foreach (var item in lern)
           {
             if (item.learnerID == UserInfo.ID)
             {
               byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
              string imageBase = Convert.ToBase64String(bytes);
              imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
            }
        }

        // This will now call the getImage function on your view.
        Clients.All.getImage(imageSource);
    }
}

关于动态代理的信息。


我的中心对嵌入在这段代码中的JavaScript发出了抱怨。而且方法参数中传递的ID从未被使用过。 - Lulutho Mgwali
好的。从中心删除id并删除js代码。 - Jamie Rees
你能否更清楚地说明如何将视图代码与其余代码链接起来? - Lulutho Mgwali
@LuluthoMgwali,我添加了一些代码注释,如果你有任何问题,请告诉我。 - Jamie Rees
非常想打分,但这并没有解决问题,只是提供了一个完全不同的选择...不是说它行不通,而是它没有解决问题的关键!而且由于他已经很困难了...引入更多复杂性并不是一个好方法..,这只是我的个人看法。 - Seabizkit
显示剩余2条评论

0
你的问题在于这里的 onclick 事件处理程序:
<img id="@item.treasureID" src="@imageSource" onclick="return MakeSure(@item.treasureID)" />

MakeSure()函数中,您没有返回任何内容。因此,您有两个选择:将MakeSure()函数更改为在结尾处返回false,或者在图像元素中的第一个函数调用后更改onclick事件以返回false,如下所示:onclick="MakeSure(@item.TreasureID); return false;" 此外,您还需要从MakeSure()函数中删除window.location.reload();
另外,似乎您在视图中混淆了DbContext,如果是这样,这是非常糟糕的做法。您应该将数据访问放在某种服务层后面,该服务层充当视图和数据之间的中介。
更新
好的,在阅读了您的问题几次后,我理解了您的问题。问题出在您的第二段代码上。
List<The_Factory_Chante.Models.Learner_Treasure> lern;
using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
{

    string imageSource = "";
    lern = db2.Learner_Treasure.ToList();
    if (lern != null)
    {
        foreach (var item in lern)
        {
            if (item.learnerID == UserInfo.ID)
            {
                byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
                string imageBase = Convert.ToBase64String(bytes);
                imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
                <img id="@item.treasureID" src="@imageSource"/>
            }
        }
    }
}

这个调用数据库并获取一个Learner_Treasure对象列表,你可以在视图上输出。服务器端代码在每次页面请求时执行,这正是正在发生的事情。它不会在没有向服务器发送请求的情况下异步更新。

你需要实现一个ajax请求来将最新的Learner_Treasure列表拉入视图中。再次回到我给出的第一个侧面说明,原因是因为你混合了你的dbcontext和你的view,并期望它能够实时更新。如果你实现一个为你的视图提供数据的层(控制器),你可以异步调用它,并且在不重新加载的情况下更新页面。

例如,你可以在你的控制器中编写一个调用以获取单个LearnerTreasure项目的json。

[HttpGet]
public ActionResult GetLearnerTreasureItem(int Id)
{
    using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext()) {
        learnerTreasureItem = db2.Learner_Treasure.FirstOrDefault(x => x.Id == Id);
        return Json(new { image = Convert.ToBase64String(learnerTreasureItem.itemImage), treasureId = learnerTreasureItem.TreasureID }, JsonRequestBehavior.AllowGet);
    }
}

然后在您的视图中使用ajax调用它,就像您使用更新一样。

$.ajax({
    cache: false,
    type: "GET",
    url: '/YOURCONTROLLERNAME/GetLearnerTreasureItem?id=1',
    contentType: 'application/json',
    dataType: "json",
    success: function (data) {
        //build image element
        var image = '<img id="' + data.treasureId + '" src="data:image/jpg;base64,' + data.image + '"';

        //add the image to where you need it.
        $(image).appendTo("body");
    },
    error: function (xhr) {
       alert("Error occurred while loading the image.");
    }
});

希望这能有所帮助。


这不会刷新页面,只是让页面不重新加载。 - Lulutho Mgwali

0

我处理这个问题的方式是创建一个局部视图,用于需要刷新的代码

public PartialViewResult UserImages(your paramaters here)
{
   your code here
}

然后在成功的$.ajax之后刷新它

var id = treshID
                $.ajax({
                    url: "../../WebService.asmx/MakeSure",
                    data: "{ 'id': '" + id + "'}",
                    dataType: "json",
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    success: function (data) {
                         $.ajax({
                              url: "/UserImages",
                              data: your data model here,
                              success(function(html)){
                               $("#yourPartialViewWrapperHere").html(html));
                               }
                         });
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {
                    }

                });

这是一段代码,它应该从服务器获取用户图像,并将它们作为模型发送到您(新创建的)部分视图。这是一个相当广泛的问题,所以我无法为您编写所有代码,但我愿意帮助您调试遇到的任何障碍。 - Zoran P.
1
@LuluthoMgwali,FYI这是目前发布的所有答案中最好的答案...你需要理解这个...如果你不明白,就向Zoran寻求更多帮助。 - Seabizkit

0

更新宝藏图片列表

<img id="@item.treasureID" src="@imageSource" onclick="return MakeSure(this, @item.treasureID)" />

在MakeSure方法中读取该参数。我只是假设Learner_Treasure图像列在名为'ulLearnerTreasure'的ul中。

function MakeSure(sender,treshID) {
          var id = treshID;
          var imgSrc = $(sender).attr("src");
                $.ajax({
                    url: "../../WebService.asmx/MakeSure",
                    data: "{ 'id': '" + id + "'}",
                    dataType: "json",
                    type: "POST",
                    contentType: "application/json; charset=utf-8",
                    success: function (data) {
                        var li = '<li><img id ="'+ treshID +'"src="'+ imgSrc  +'" /></li>';
                        $("#ulLearnerTreasure").append(li);
                    },
                    error: function (XMLHttpRequest, textStatus, errorThrown) {

                    }

                });

            };

0
我会使用HtmlHelpers来实现它,就像这样:(正如有人建议的那样,直接使用db代码并不是一个好的做法,你需要改变这种做法。)
public static class HTMLHelpers
{
    public static IHtmlString TreasureImages(this HtmlHelper helper, List<The_Factory_Chante.Models.Learner_Treasure> lern)
    {
        StringBuilder sb = new StringBuilder();
        using (The_Factory_Chante.Models.The_FactoryDBContext db2 = new The_Factory_Chante.Models.The_FactoryDBContext())
        {

            string imageSource = "";
            lern = db2.Learner_Treasure.ToList();
            if (lern != null)
            {
                foreach (var item in lern)
                {
                    if (item.learnerID == UserInfo.ID)
                    {
                        byte[] bytes = db2.Treasures.FirstOrDefault(au => au.treasureID == item.treasureID).itemImage;
                        string imageBase = Convert.ToBase64String(bytes);
                        imageSource = string.Format("data:image/gif;base64,{0}", imageBase);
                        sb.Append("<li><img id='@item.treasureID' src='@imageSource'/></li>");
                    }
                }
            }
        }
        return new HtmlString(sb.ToString());
    }
}

您的图片占位符:

<ul id="TreaureImagesSection">
</ul>

在您的cshtml页面中,使用此脚本加载列表,第一次或每当您需要更新的列表。
<script>
    $.ajax({
    cache: false,
    type: "GET",
    url: '/YOURCONTROLLER/TreasuresList',
    contentType: 'application/json; charset=utf-8',
    success: function (data) {  // the data returned is List<The_Factory_Chante.Models.Learner_Treasure>
        $("#TreaureImagesSection").html('@Html.TreasureImages(data)');
    },
    error: function (xhr) {
        alert("Error occurred while loading the image.");
    }
});
</script>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接