jQuery $ .each()使用webservice更新div

时间:2013-10-02 20:29:21

标签: c# jquery html ajax web-services

我有以下网络服务:

[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

我希望我已经解释得这么好了。先感谢您。

3 个答案:

答案 0 :(得分:3)

您需要将所有新的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内容,这就是为什么最后一次迭代是您最终看到的唯一一次。

答案 1 :(得分:1)

这一行:

$('#<%=lblOutput.ClientID%>').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);
},

答案 2 :(得分:1)

2回答说你做错了什么,但我会抓住机会向你展示一种更简单的方式

使用 JsRender http://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/