【问题标题】:jQuery $.each() update div using webservicejQuery $.each() 使用 web 服务更新 div
【发布时间】:2013-10-09 09:18:54
【问题描述】:

我有以下网络服务工作:

[WebMethod]
[ScriptMethod(UseHttpGet = false, ResponseFormat = ResponseFormat.Json)]
public List<ServerRoomDisplay> GetData(List<string> urls)
{
List<ServerRoomDisplay> returnList = new List<ServerRoomDisplay>();
foreach (var uri in urls)
{
    XDocument xdoc = XDocument.Load(uri);
    IEnumerable<XElement> serv = xdoc.Elements();

    string ur = "";
    string room = "";
    string temp = "";
    string hum = "";
    string dew = "";
    foreach (var ser in serv)
    {
        room = ser.Attribute("host").Value;
        ur = "http://" + ser.Attribute("address");
        temp = ser.Descendants("devices").Descendants("device").Descendants("field").Where(x => (string)x.Attribute("key").Value == "Temp").FirstOrDefault().Attribute("value").Value.ToString();
        hum = ser.Descendants("devices").Descendants("device").Descendants("field").Where(x => (string)x.Attribute("key").Value == "Humidity").FirstOrDefault().Attribute("value").Value.ToString();
        dew = ser.Descendants("devices").Descendants("device").Descendants("field").Where(x => (string)x.Attribute("key").Value == "Dewpt").FirstOrDefault().Attribute("value").Value.ToString();
        returnList.Add(new ServerRoomDisplay
            {
                RoomName = room,
                Url = ur,
                Temperature = temp,
                Humidity = hum,
                DewPoint = dew,
            });             
    }
}
return returnList;
}

然后我通过 ajax 调用传递参数。请注意,此方法以递归方式运行,以更新 div 中的数据......就像 eTrade 上的股票代码或其他东西。

(function poll() {
        var pageUrl = '<%=ResolveUrl("~/Reporting/GetXMLData.asmx")%>'
        var urls = ["http://aaa/data.xml", "http://bbb/data.xml", "http://ccc/data.xml"];
        var jsonText = JSON.stringify({ urls: urls });
        $.ajax({
            type: "POST",
            contentType: "application/json; charset=utf-8",
            url: pageUrl + "/GetData",
            data: jsonText,
            success: function (msg) {
                var res = msg.d;
                $.each(res, function (i, item) {
                    $('#<%=lblOutput.ClientID%>').html(res[i].RoomName);
                });
            },
            dataType: "json",
            complete: poll,
            timeout: 3000
        });
    })();

然后产生这个响应:

[{"__type":"ServerRoomDisplay",
 "Url":"http://address=\"aaa\"",
 "RoomName":"aaa MDF Room 500",
 "Temperature":"74.99",
 "Humidity":"38",
 "DewPoint":"47.65",
 "AlarmOne":null,
 "AlarmTwo":null,
 "AlarmThree":null,
 "AlarmFour":null
 },
 {"__type":"ServerRoomDisplay",
 "Url":"http://address=\"bbb\"",
 "RoomName":"bbb Room 298",
 "Temperature":"77.73",
 "Humidity":"39",
 "DewPoint":"50.79",
 "AlarmOne":null,
 "AlarmTwo":null,
 "AlarmThree":null,
 "AlarmFour":null
 },
 {"__type":"ServerRoomDisplay",
 "Url":"http://address=\"ccc\"",
 "RoomName":"ccc Room 601",
 "Temperature":"75.32",
 "Humidity":"49",
 "DewPoint":"54.83",
 "AlarmOne":null,
 "AlarmTwo":null,
 "AlarmThree":null,
 "AlarmFour":null
 }];

如您所见,它是 json 响应中返回的 3 个完整对象。 然后我有输出 div 来放置数据

<div>
    <asp:Label ID="lblOutput" runat="server" />
</div>

从上面的 jquery 中,我通过尝试仅将“RoomName”列出到 div 中进行测试。当我这样做时,它只会打印出最后一个项目,即“ccc Room 601”,这是 div 中唯一的内容。

有人可以帮我列出所有对象,然后只更新更改的数据吗?基本上它应该重新编写 lblOutput 并仅更改温度、湿度和露点信息。但它应该打印出所有 3 个对象。 换句话说,我应该得到以下信息(现在仅适用于 RoomName)

aaa MDF Room 500
bbb Room 298
ccc Room 601

我希望我已经充分解释了这一点。先感谢您。

【问题讨论】:

  • 我认为您只需将.html() 替换为.append()

标签: c# jquery html ajax web-services


【解决方案1】:

您需要将所有新的 html 连接成一个字符串并立即追加。

        success: function (msg) {
            var res = msg.d;
            var outhtml = "";
            $.each(res, function (i, item) {
                outhtml+=res[i].RoomName;
            });
            $('#<%=lblOutput.ClientID%>').html(outhtml);
        },

您当前的方式只是在每次迭代时覆盖输出 div 的 html 内容,这就是为什么最后一次迭代是您最后看到的唯一一个。

【讨论】:

  • 哭笑不得!我整天都在做这件事,你们设法在几分钟内弄清楚了。非常感谢 Kevin B 并感谢你的尝试。非常感谢!
【解决方案2】:

这一行:

$('#&lt;%=lblOutput.ClientID%&gt;').html(res[i].RoomName);

...覆盖元素中的所有 html。所以每次在循环内调用,都会完全覆盖上一次调用的html。

试试这个:

success: function (msg) {
    var res = msg.d;
    var accumulated_html = '';
    $.each(res, function (i, item) {
        accumulated_html += res[i].RoomName;
    });
    $('#<%=lblOutput.ClientID%>').html(accumulated_html);
},

【讨论】:

  • 糟糕,看来我是和 Kevin B 同时发布的。
【解决方案3】:

2 回答说你做错了什么,但我会借此机会向你展示一个更简单的方法

使用 JsRenderhttp://www.jsviews.com/#home


在您的页面中(或通过外部文件)并在已加载 JsRender 文件之后:

<script id="serversTemplate" type="text/x-jsrender">
    <li>
        <h3><a href="{{:Url}}" target"_blank">{{:RoomName}}</a></h3>
        <ul>
            <li>{{:Temperature}}<span>Temperature</span></li>
            <li>{{:Humidity}}<span>Humidity</span></li>
            <li>{{:DewPoint}}<span>DewPoint</span></li>
            <li>...</li>
        </ul>
    </li>
</script>

假设您将删除 ASP.NET 控件并拥有类似的内容:

<ul id="lblOutput"></ul>

您的 ajax success 调用应该是:

success: function (msg) {
    $("#lblOutput").html(
        $("#serversTemplate").render(msg.d);
    );
}

一个简单的演示,没有 JsBin 中的 ajax 调用:http://jsbin.com/aPILewe/1/


来自评论,一个小更新

<li class="{{if Temperature < 75}}good{{else}}bad{{/if}}">

演示现在在:http://jsbin.com/aPILewe/2/

【讨论】:

  • 哇,这太酷了。如果温度高于某个水平,我什至需要将持有的 div 显示为红色,所以这似乎是一种很好的方法,因为我可以使用它构建所需的 div。我会试试看。也谢谢你。
  • 答案已更新为 if 约束。您可以在文档中阅读更多关于 {{if}} 的信息:jsviews.com/#iftag
  • 不确定您是否可以进一步提供帮助,但是当我在我的 html 页面中使用 jsrender 文件时,它会返回一个错误,提示“未找到 jsviews.min.js.map”。该文件在项目中并在我的页面中正确引用。
  • 您可以在jsdelivr.com/#!jsrender 或谷歌搜索cdn jsrender 中找到CDN :)
  • 顺便说一句,很高兴你喜欢它...自从 jQuery 模板以来,我一直是 JsRender 的粉丝,每次使用它时我都越来越喜欢它。创建者是Boris Moore
猜你喜欢
  • 2018-05-19
  • 1970-01-01
  • 1970-01-01
  • 2012-04-09
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-08-07
相关资源
最近更新 更多