2011-10-31 68 views
0

我希望能够让ajax在每次触发时更新span标记中的文本。将内容动态追加到使用jQuery的元素

$.ajax({ 
    type: 'GET', 
    url: "JSON URL", 
    cache: false, 
    contentType: 'application/json', 
    dataType: 'json', 
    success: function(html){ 
     $('#status_frame_span').prepend(html.status) 
     alert(html.status) 
    }, 
    error: function(jq,stats,errmes) { 
      alert("Error" + errmes); 
      } 
    }); 

第一次启动时,从URL返回的json的内容被正确地预置在span上。但是对于随后的激发,它不会被更新。

如何确保在每次点火时内容得到更新?

回答

0

什么触发到服务器的呼叫?它是在更新HTML内部的按钮或链接吗?如果是这样,更新UI时事件处理程序可能会丢失。或者,其他事情正在丢失事件处理程序,它不会调用该方法来激发获取请求等。

HTH。

+0

这是一个rails应用程序的内部。 JavaScript在初始加载页面时被触发。在原始页面内有一些将html加载到iframe中的链接。该HTML负载触发代码的新射击。我有一个rabbitmq服务器,并且有一部分从队列中读取消息。我想模拟Web前端到日志记录系统,以便当新消息被注入到队列中时,它们将显示在网页上。 –

0

当然,您的视图只更新一次:您只需要调用一次服务器!

如果根据您的标签所示,您正在使用long polling(请确认是这种情况,我不确定您对事件,投票和远程呼叫有什么清晰的概念),那么您每次收到一个请求时都需要提出新的请求!

在您的successerror处理程序中,您都必须递归地向服务器发出AJAX调用。您还必须为呼叫设置超时时间,这可能会取消它们并在例如30秒后开始新的呼叫。

您还应该为递归调用实施某种限制,除非您99.99%确定服务器页面永远不会发送错误。否则,你会杀死你的客户。

为了完整起见,我必须补充说这对HTML5 SSEWebSocket来说是一个很好的用例。但他们尚未准备好生产用途。

+0

我们在生产模式下使用socket.io时没有任何问题:) – sled

+0

当然,如果您使用的库提供[all fallback](http://socket.io/#browser-support)并隐藏它们在一个漂亮的API后面,这没有问题:)这并不意味着WebSocket作为一项技术本身就是生产环境。如果您要在您的网站中实施[草稿规范](http://dev.w3.org/html5/websockets/),您会对浏览器支持和维护感到非常失望;) – MattiSG

0

它不会以这种方式工作 - 如果调用成功回调 - 连接已关闭,所以一旦请求完成,您的长轮询就会失效。

长轮询背后的想法是,你保持连接活着。正确配置您的服务器,以便尽可能长时间地保持连接打开(尽可能设置超时)。

下面是从我的茶歇(未测试)的方法:

服务器

  • 每个消息具有分隔符结束:: PART ::
  • 服务器必须正确配置这意味着将超时设置得尽可能高!

客户端(浏览器)

// setup longpoll, check all 250ms for new data in the stream 
var myPoller = new LongPoll('some-url', 250); 

// bind connection lost 
myPoller.bind('longpoll:end', function(evt) { 
    alert('connection lost - trying reconnect'); 
}); 

// bind error event 
myPoller.bind('longpoll:error', function(evt, errmsg) { 
    alert('error: ' + errmsg); 
}); 

// bind data event 
myPoller.bind('longpoll:data', function(evt, data) { 
    try { 
    // try to parse json 
    data = $.parseJSON(data); 
    // prepend 
    $('#status_frame_span').prepend(data.status); 
    } catch(e) { 
    // invalid json 
    alert('invalid json: ' + data); 
    } 
}); 

longpoll。js

var LongPoll = function(url, timeout) { 

    // url we connect to 
    this.url  = url; 

    // running? 
    this.isRunning = false; 

    // timer for checking the stream 
    this.timer  = null; 

    // the length of the received data 
    this.dataLength = 0; 

    /* 
    The messages has to be delimited by the delimiter like: 
    first data::PART::second data::PART::third data::PART:: 
    */ 

    this.delimiter = RegExp.new("::PART::", 'gm'); 


    // residue from previous transmission 
    this.residue = '' 
}; 


// connect to server 

LongPoll.prototype.connect = function() { 

    var self = this; 

    // reset data length 
    this.dataLength = 0; 

    // reset residue 
    this.residue = ''; 

    // start ajax request 
    this.xhr = $.ajax({ 
    type: 'GET', 
    url: this.url, 
    cache: false, 
    contentType: 'application/json', 
    dataType: 'text', 
    success: function(){ 
     // the connection is dead! 
     self.xhr = null; 

     // trigger event 
     $(self).trigger('longpoll:end'); 

     // reconnect if still running 
     if(self.isRunning) { 
     self.connect(); 
     } 
    }, 
    error: function(jq,stats,errmes) { 
     // stop timer and connection 
     self.stop(); 
     $(self).trigger('longpoll:error', errmes); 
    } 
    }); 
}; 


// process data 
LongPoll.prototype.process = function(buffer) { 

    var self = this; 

    // check if there is anything new 
    if(buffer.length > this.dataLength) { 

    var newData = this.residue + buffer.substring(this.dataLength, buffer.length); 

    // reset residue 
    this.residue = ''; 

    // store the new position 
    this.dataLength = buffer.length; 

    // split data 
    var dataParts = newData.split(this.delimiter); 

    // how many full parts? 
    var fullParts = newData.match(this.delimiter).length; 

    if(dataParts.length > fullParts) { 
     // pop residue (incomplete message) 
     this.residue += dataParts.pop(); 
    }  

    $.each(dataParts, function(index, part) { 
     // broadcast data parts 
     $(self).trigger('longpoll:data', $.trim(data)); 
    });  
    } 
}; 


// check for data 
LongPoll.prototype.receive = function() { 

    var self = this; 

    // connection still there? 
    if(this.xhr) { 
    // process buffer 
    this.process(this.xhr.responseText); 
    } 
}; 


// start long poll 

LongPoll.prototype.start = function() { 

    var self = this; 

    // set flag 
    this.isRunning = true; 

    this.timer = setInterval(function() { self.receive(); }, this.timeout); 

    this.connect(); 
}; 

// stop long poll 

LongPoll.prototype.stop = function() { 

    // set flag 
    this.isRunning = false; 

    // clear timer 
    clearInterval(this.timer); 

    if(this.xhr) { 
    // abort request 
    this.xhr.abort(); 
    } 
}; 
+0

感谢您的阅读,并试图帮助它:) –