0

我有以下网络服务工作:

[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

我希望我已经解释得足够好。先感谢您。

4

3 回答 3

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

于 2013-10-02T20:34:52.557 回答
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>

您的 ajaxsuccess调用应该是:

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/

于 2013-10-02T20:52:44.147 回答
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);
},
于 2013-10-02T20:37:26.193 回答