2014-10-07 55 views
3

我们在WinJS中的应用程序中有一种情况,我们从磁盘上的文件中读取序列化数据,并根据页面访问文件的不同部分。WinJS - 防止两个快速按钮

我们遇到的问题是,当用户双击一个控件,按钮,列表视图等,系统会尝试读取文件两次,并零星爆炸。

在WinJS中是否有推荐的路线来防止或处理控件的双重按压?除了像按下时手动禁用和重新启用所有按钮之类的东西?

我们已经看了一些选项,包括重写addEventListener,但没有一个是完美的,在这方面的任何建议将不胜感激。

附加说明:虽然在这个例子中,问题在于读取文件,但我们有其他应用程序在列表上执行快速双击会尝试导航到页面两次(并将其添加到nav.history两次),所以它似乎有这样的事情可能发生的地方和症状。

+0

你可以有它每次按下诸如 “ProcessingValue” 所有按钮继续之前检查设置一个变量? – 2014-10-07 23:26:47

+0

嗨Nate,这是我们正在寻找的建议之一,缺点是,这可能会在应用程序的很多领域触发,我们需要多次编写相同的代码,或者看看某种方式的重写addEventListener并使所有底层侦听器函数返回承诺,以便我们可以在处理完成后设置“处理值”。 – dougajmcdonald 2014-10-08 09:06:10

回答

0

最好的方法是在处理时禁用按钮,并在完成后重新启用它们。如果事情花费比预期更长的时间,这将向用户提供适当的反馈。

您可以通过数据绑定禁用它们,而不是手动设置它们。

HTML

<button id="button1" data-win-bind="disabled: disabled">Click</button> 
<button id="button2" data-win-bind="disabled: disabled">Click</button> 
<button id="button3" data-win-bind="disabled: disabled">Click</button> 
<button id="button4" data-win-bind="disabled: disabled">Click</button> 

的JavaScript

var bindingSource; 

app.onactivated = function (args) { 
    if (args.detail.kind === activation.ActivationKind.launch) { 
     if (args.detail.previousExecutionState !== activation.ApplicationExecutionState.terminated) { 
      // TODO: This application has been newly launched. Initialize 
      // your application here. 
     } else { 
      // TODO: This application has been reactivated from suspension. 
      // Restore application state here. 
     } 
     args.setPromise(WinJS.UI.processAll()); 

     var disabledContext = { disabled: false } 

     var btn = document.getElementById("button1"); 
     btn.addEventListener("click", buttonClickHandler, false); 
     WinJS.Binding.processAll(btn, disabledContext); 

     btn = document.getElementById("button2"); 
     btn.addEventListener("click", buttonClickHandler, false); 
     WinJS.Binding.processAll(btn, disabledContext); 

     btn = document.getElementById("button3"); 
     btn.addEventListener("click", buttonClickHandler, false); 
     WinJS.Binding.processAll(btn, disabledContext); 

     btn = document.getElementById("button4"); 
     btn.addEventListener("click", buttonClickHandler, false); 
     WinJS.Binding.processAll(btn, disabledContext); 

     bindingSource = WinJS.Binding.as(disabledContext); 
    } 
}; 

function buttonClickHandler(eventInfo) { 
    bindingSource.disabled = true 

    WinJS.Promise.timeout(5000).then(function (c) { 
     bindingSource.disabled = false 
    }); 
} 

--Rob

+0

嗨罗布,除了我们非常需要在任何新闻,按钮,列表,超链接等等上实现这一点,这些都有我们需要实现的稍微不同的“禁用”行为。 此外,我们建议在按钮按下5秒超时将“可能”工作,除了似乎我们没有一个有效的方式知道我们的按钮上的'工作'是什么时候完成的,除非每个处理程序我们用过的人回复了一个承诺,而有些人则承诺,许多人不承认,将这些变更全部以这种方式工作是相当重要的。 – dougajmcdonald 2014-10-08 09:10:00

+0

5秒超时是您的应用程序需要做的任何工作的占位符。你不会想要一个真正的应用程序。大多数控件将以相同的方式绑定到禁用,并且您可以在绑定源中包含其他属性并编写一个可以将它们全部设置为禁用/启用的函数。如果您无法知道工作何时完成,那么在工作进行时防止双重访问的任何方法都很困难。 – 2014-10-08 20:10:49

+0

提示:如果承诺运行到错误状态,则应将残疾人设置为false,否则该按钮将被永久禁用。对于尚未缺失的'WinJS.Promise.finally'方法,这是一个完美的例子:)然后你可以直接写'WinJS.Promise.timeout(5000).finally(function(){bindingSource.disabled = false;});' – philk 2015-03-11 09:50:55