在第三方库的回调中松开ember上下文

时间:2014-08-28 04:06:15

标签: ember.js

我在接收模型的webocket更新的路线中有以下代码。问题是当这一行执行时

setTimeout(self.stompConnect, 10000);

我无法再访问stompConnect方法顶部的Ember.Route Ember对象。

var self = this; //no longer pointing to my route

如何在这样的第三个pary库中的回调中维护ember上下文?这与websockets或库无关,因为我与另一个有回调的第三方库有同样的问题。

我想我需要使用.bind()或其他东西,但我不知道正确的语法。

stompClient : null,

activate : function() {
    this.stompConnect();
},

stompConnect : function() {
    var self = this;

    var connectCallback = function(frame) {
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/models/update', function(payload){
            var model = JSON.parse(JSON.parse(payload.body));
            var modelName = Object.keys(model)[0];
            var modelPayload = model[modelName];

            self.store.push(modelName, modelPayload);

        });
    };

    var errorCallback = function (error) {
        console.log('STOMP: ' + error);
        setTimeout(self.stompConnect, 10000); //when stompConnect() is called, the ember context is lost :(
        console.log('STOMP: Reconecting in 10 seconds');
    };

    var url = ... ;
    var socket = new SockJS(url);
    var stompClient = Stomp.over(socket);
    stompClient.connect({}, connectCallback, errorCallback);

    this.set('stompClient', stompClient);
},

deactivate : function() {
    this.get('stompClient').disconnect();
},

1 个答案:

答案 0 :(得分:0)

基本上你在回调中有一个回调。因此需要在两个回调中传递上下文。 self将在errorCallBack中运行,但需要再次设置才能在stompConnect中运行。我建议您使用run.latersetTimeOut。所以这里是代码。

stompClient : null,

activate : function() {
    this.stompConnect();
},

stompConnect : function() {
    var self = this;

    var connectCallback = function(frame) {
        console.log('Connected: ' + frame);
        stompClient.subscribe('/topic/models/update', function(payload){
            var model = JSON.parse(JSON.parse(payload.body));
            var modelName = Object.keys(model)[0];
            var modelPayload = model[modelName];

            self.store.push(modelName, modelPayload);

        });
    };

    var errorCallback = function (error) {
        console.log('STOMP: ' + error);

        Ember.run.later(this, this.stompConnect, 1000);
        //or you can also use
        //setTimeout(this.stompConnect.bind(this), 10000); when stompConnect() is called, the ember context is lost :(
        console.log('STOMP: Reconecting in 10 seconds');
    };

    var url = ... ;
    var socket = new SockJS(url);
    var stompClient = Stomp.over(socket);
    stompClient.connect({}, connectCallback, errorCallback.bind(this));

    this.set('stompClient', stompClient);
},

deactivate : function() {
    this.get('stompClient').disconnect();
}

我更喜欢使用.bind()而不是var self = this;。但这取决于。