Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/366.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 如何在knockout.js中检测除更改事件之外的更改_Javascript_Jquery_Knockout.js - Fatal编程技术网

Javascript 如何在knockout.js中检测除更改事件之外的更改

Javascript 如何在knockout.js中检测除更改事件之外的更改,javascript,jquery,knockout.js,Javascript,Jquery,Knockout.js,我正在使用knockout.js。我创建了一个视图模型,比如说testViewModel,它只有一个可观察属性testProperty function testViewModel() { var self = this; self.testProperty = ko.observable("Initial"); } 然后,我创建了一个span,其中反映了testProperty的更改值,并创建了一个输入文本字段,通过它我们可以更改testProperty值 <span d

我正在使用knockout.js。我创建了一个视图模型,比如说
testViewModel
,它只有一个可观察属性
testProperty

function testViewModel()
{
  var self = this;

  self.testProperty = ko.observable("Initial");

}
然后,我创建了一个
span
,其中反映了
testProperty
的更改值,并创建了一个
输入文本字段
,通过它我们可以更改
testProperty

 <span data-bind="text: testProperty"></span><br />
 <input type="text" data-bind="value: testProperty" />

我创建了一个。当在输入文本字段上执行focusout事件时,observable属性值似乎会更新

现在我的问题是,我们可以将可观测属性值更新事件从focusout更改为其他事件吗。我还创建了一个保存按钮。是否有任何方法仅在按下保存按钮时更新可观察属性值

我正在尝试创建一个应用程序,其中用户可以创建和保存其配置文件,并可以编辑保存的配置文件。我在创建和编辑表单中使用相同的可观察属性,并且这些属性是可观察的。因此,当用户编辑其配置文件时,ui不应
直到用户按下“保存”按钮,才会更新。这是我的目标。请帮助我解决此问题?

您最简单的方法是为每个属性设置一个阴影属性。因此,当单击“保存”时,可以将一个属性绑定到文本框,并仅将值复制到另一个属性,即绑定到其他UI元素的属性

请看这里:

使用两个模型和$.extend从一个模型复制到另一个模型的更简单方法:

更新,实际上是划伤,这似乎不起作用。我试过这样做:


它第一次起作用,但在使用$.extend复制模型之后,它似乎也复制了所有绑定,因此它只起作用一次

我建议使用testProperty和testProperty_temp。将输入绑定到temp,单击按钮时,将testProperty设置为testProperty\u temp

function testViewModel()
{
   var self = this;

   self.testProperty = ko.observable("Initial");
   self.testProperty_temp = ko.obserable("");
   self.save = function() { self.testProperty(self.testProperty_temp()); }
 }

希望这有助于

另一种方法,与Matt Burland的建议相同:

基本上,将您的输入和按钮包装在表单中,并将表单绑定到submit:这由ViewModel上的方法处理。请参阅我在内联中所作的评论,但这里是为那些不想使用JSFIDLE的人准备的:

<span data-bind="text: testProperty"></span><br />
<!-- wrap the input and button in a form and
   data-bind to submit, with a reference
   to a handler on your viewmodel -->
<form data-bind="submit: updateProfile">
<!-- this must be bound to your shadow value -->
<input type="text" data-bind="value: _tmpTestProperty" />
<button type="submit">save</button>
</form>​

这样,当您失去对文本输入框的关注时,您的值不会改变,但只有在您提交表单时才会更新。

谢谢回复,但我有很多属性,所以这是一种将属性计数加倍(意味着创建每个属性的副本)的好做法吗?谢谢回复,但我有很多属性,因此,这是一个很好的做法来增加属性计数(意味着创建每个属性的副本)吗?我会考虑,无论是使用KokOutt还是jQuery还是普通的JavaScript,需要多少东西来保持积极更新,并且只更新或绑定属性,我必须动态更新。我不知道Knockout的性能开销是多少,或者字段边界的上限是多少(如果有的话),但在其他条件相同的情况下,请使用Occam的剃刀:最简单的解决方案就是最好的解决方案。如果您发现自己过于复杂,可能是时候退后一步,重新评估您试图解决的问题,看看是否有更简单的解决方案。谢谢您的回复,但我有很多属性,所以这是一个好的做法,将属性数加倍(意味着创建每个属性的副本)?@TomRider:另一种方法是创建两个单独的模型。如果页面上有不同的父DOM元素,则可以绑定多个模型。然后可以将一个绑定为可编辑,另一个绑定为显示。单击“保存”时,只需将可编辑值复制到显示值。或者更好不过了。也许比每个变量都有两个副本要容易一些?@TomRider:我在回答中添加了另一个版本,它通过只保留两个模型消除了保留每个属性副本的复杂性。只要可以将每个模型绑定到不同的DOM元素,它就可以工作。或者,也可以将它们嵌套在单亲视图模型中,以删除该限制。
function testViewModel()
{
  var self = this;

  self.testProperty = ko.observable("Initial");
  // Create the "shadow" property
  // and prepopulate it with testProperty's value
  self._tmpTestProperty = ko.observable(self.testProperty());

  // Create our form handler
  self.updateProfile = function(val){
    // set the testProperty value to the 
    // value of the shadow property
    self.testProperty(self._tmpTestProperty());
  };

}

ko.applyBindings(new testViewModel());​