2013-07-17 69 views
2

我有我與GoInstant同步的文本區域。這裏是代碼的樣子:兩個同步事件創建一個無限循環

var myRoom = platform.room('myRoom'); 
var myKey = myRoom('myKey'); 

// Listen to set events on the platform key and update a textarea 
myKey.on('set', function(textAreaContent) { 
    $('textarea').val(textAreaContent); 
}); 

// When the textarea changes, set the platform key 
$('textarea').on('change', function(){ 
    var textAreaContent = $(this).val(); 
    myKey.set(textAreaContent, function(err) { 
    if (err) throw err; 
    }); 
}) 

此更新一個文本字段,即當在改變textarea的值會創建一個無限循環,這會觸發一個平臺密鑰更新,這反過來又改變的價值textarea的無限...

編輯:基於我想出了下面的構造頂部的答案:

function BounceProtection() { 
    var remoteUpdate = false; // remote toggle 
    this.local = function(cb) { 
    if (remoteUpdate) return; 
    cb(); 
    }; 
    this.remote = function(cb) { 
    remoteUpdate = true; 
    cb(); 
    remoteUpdate = false; 
    }; 
} 

通過這種方式,爲需要保護多個按鍵甚至與異步性,我可以生成bounceProtection對象的js。

var myKeyBP = new BounceProtection(); 
+1

怎麼會這樣? 'on(「set」)'監聽器中的'$ textarea.val()'不會觸發'change'事件... – Bergi

+0

它會在遠程用戶的myKey.on被觸發時觸發,然後觸發一個change事件然後做了myKey.set大家遠程...(循環) – Pykler

+0

然後,只需刪除該代碼觸發'change'事件的textarea的時候'的'myKey'發生set'事件? – Bergi

回答

5

防止無限傳播循環的快速方法:

// Infinite loop prevention 
var bounceProtection = { 
    remoteUpdate: false, // remote toggle 
    local: function(cb) { 
    if (this.remoteUpdate) return; 
    cb(); 
    }, 
    remote: function(cb) { 
    this.remoteUpdate = true; 
    cb(); 
    this.remoteUpdate = false; 
    } 
}; 

var myRoom = platform.room('myRoom'); 
var myKey = myRoom.key('myKey'); 

myKey.on('set', function(textAreaContent) { 
    bounceProtection.local(function() { 
    $('textarea').val(textAreaContent); 
    }); 
}); 

$('textarea').on('change', function(){ 
    var textAreaContent = $(this).val(); 
    bounceProtection.remote(function() { 
    myKey.set(textAreaContent, function(err) { 
     if (err) throw err; 
    }); 
    }); 
}); 
+0

輕微修改的bounceProtection ......單身只爲一組/改變對工作。我們需要爲每個我們想要保護的set/change對創建bounceProtection對象。改變bounceProtection到OBJ發生器(出廠/構造函數/ ...)功能...查看上述更新。 – Pykler

1

編輯文本區域之前,只需刪除監聽器,然後重新應用它(我還緩存您的textarea給你們,你們不要搜索每個觸發事件上的DOM)。

我還建議你給textarea一個ID屬性,因爲看起來你正在使用一個textarea,但做了一個標籤搜索,這是低效的,並且通過向該頁面添加另一個textarea容易被破壞。

var myRoom = platform.room('myRoom'); 
var myKey = myRoom('myKey'); 

var $textarea = $('textarea'); 

function setKey() { 
    var textAreaContent = $(this).val(); 
    myKey.set(textAreaContent, function(err) { 
    if (err) throw err; 
    }); 
} 

// Listen to set events on the platform key and update a textarea 
myKey.on('set', function(textAreaContent) { 
    $textarea.off('change', setKey); // Remove listener 
    $textarea.val(textAreaContent); 
    $textarea.on('change', setKey); // Reapply listener 
}); 

// When the textarea changes, set the platform key 
$textarea.on('change', setKey); 
+0

這應該工作。其他答案中的bounceProtection片段是一個更通用的解決方案。 – Pykler

0

另一種可能的方法是在設置值之前先比較值。可以說,沒有足夠一般在事件沒有可比的結果,但在這種情況下,該解決方案將工作的情況。

myKey.on('set', function(textAreaContent) { 
    var $textarea = $('textarea'); 
    if ($textarea.val() !== textAreaContent) { // compare values first 
    $textarea.val(textAreaContent); 
    } 
}); 

// When the textarea changes, set the platform key 
$('textarea').on('change', function(){ 
    var textAreaContent = $(this).val(); 
    myKey.set(textAreaContent, function(err) { 
    if (err) throw err; 
    }); 
}) 
相關問題