Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/468.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_Knockout.js_Observable - Fatal编程技术网

Javascript 如何使用knockout.js订阅变量状态更改

Javascript 如何使用knockout.js订阅变量状态更改,javascript,knockout.js,observable,Javascript,Knockout.js,Observable,下面是我想要实现的一个基本的knockout.js文件: 它做了我想做的事,但不是以我想要的方式 为了完整起见,我将在此处重复上述fiddle代码的部分内容: 在视图中,我得到了遍历一组可观察项的每个: <div data-bind="foreach: $root.availableItems"> <div class="switchBox"> <div class="switchName">&

下面是我想要实现的一个基本的knockout.js文件:

它做了我想做的事,但不是以我想要的方式

为了完整起见,我将在此处重复上述fiddle代码的部分内容:

在视图中,我得到了遍历一组可观察项的每个:

<div data-bind="foreach: $root.availableItems">
 <div class="switchBox">
  <div class="switchName"><strong data-bind="text: '&nbsp;' + name()"></strong></div>
   <label class="Switch">
    <input type="checkbox" data-bind="checked: state">
   </label>
 </div>
如您所见,我还有一个函数,在该函数中,我使用可观察项初始化这些项中的每一项:

function Item(id, name, state, onChange) {
  var self = this;

  self.id = ko.observable(id);
  self.name = ko.observable(name);
  self.state = ko.observable(state);

  self.state.subscribe(function(newValue) {
    onChange(self, newValue);
  });
}
数组中的每个项都有状态变量(state1、state2、state3),这些变量是布尔值,它们控制哪个chekbox被选中,哪个不被选中。在本例中,它们是在ViewModel的Begining处设置的:

var state1 = true;
var state2 = false;
var state3 = false;
实际上,state1、state2和state3是从服务器映射的。我想要实现的是,在我用起始状态值初始化我的项目之后,我希望在state1、state2和state3的每次更改时订阅它们,以便根据从服务器接收的值选中或不选中复选框

当前,fiddle中的代码通过访问availableItems数组实现状态更改,如下所示:

    setInterval(()=>{
    var itemNoThatChanged=Math.floor(Math.random()*3);
    var newState=Math.random()>0.5;
   self.availableItems()[itemNoThatChanged].state(newState)
    },1000)
这里的问题是,不是state1或state2或state3中的更改导致了更改,而是直接访问可用项数组

如何更改此代码,以使state1、state2和state3的更改导致上述行为,如在fiddle中

我需要尽可能减少对现有代码方法的更改,因为它会影响原始代码中的许多其他内容


这是否可行?如果可以,请有人解释一下如何在knockout.js中编写此代码?

因为您希望对现有代码进行最小的更改
state1
state2
state3
变量声明为可观察变量

var state1 = ko.observable(true);
var state2 = ko.observable(false);
var state3 = ko.observable(false);
调整您的
项目
以接受并按原样使用这些项目,而不是设置可观察项目本身

function Item(id, name, state, onChange) {
    var self = this;

    self.id = ko.observable(id);
    self.name = ko.observable(name);
    self.state = state;

    self.state.subscribe(function(newValue) {
        onChange(self, newValue);
  });
}

下面的可运行示例显示,
state1
(可观察)变量的值更改(从计时器回调触发)也会影响复选框,而无需任何
数组
访问


功能项(id、名称、状态、onChange){
var self=这个;
self.id=ko.可观察(id);
self.name=ko.observable(名称);
self.state=状态;
self.state.subscribe(函数(newValue){
onChange(self,newValue);
});
}
函数ViewModel(){
var self=这个;
var state1=可观察到的ko(真);
var state2=可观察到的ko(假);
var state3=可观察到的ko(假);
self.availableItems=ko.observearray([]);
self.activeItemss=ko.computed(函数(){
返回self.availableItems().filter(函数(项){
返回item.state();
});
});
self.onItemStateChange=函数(项,newValue){
console.log(“状态更改事件:“+item.name()+”(“+newValue+”)”);
};
self.init=函数(){
自助服务([
新项目(1,“项目1”,状态1,自身状态变更),
新项目(2,“项目2”,状态2,自身状态变更),
新项目(3,“项目3”,状态3,自我状态变更)
]);
设置间隔(()=>{
//模拟状态的变化1
state1(!state1());
}, 1000);
};
}
var viewModel=新的viewModel();
应用绑定(视图模型);
init()



pfx,非常感谢您的回答。这就是我要找的。只有一个问题……如果state1、state2和state3是映射到usping ko.mapping.fromJS映射的变量,那么是否可以使用相同的方法?在这种情况下,我是否也应该更改其他内容?@johndoe我的第一个想法是,它应该按原样工作,因为ko.mapping实用程序只是设置可观察对象(此处:state1、2和3)。。。但是我没有使用ko.mapping来提供100%的保证。我尝试了上面的方法。由于以下错误而失败:Uncaught TypeError:self.state.subscribe不是一个函数我想更好的问题应该是:如何对其进行编码,以便可以手动控制taht复选框,并使用从服务器端接收的状态变量。。。。
function Item(id, name, state, onChange) {
    var self = this;

    self.id = ko.observable(id);
    self.name = ko.observable(name);
    self.state = state;

    self.state.subscribe(function(newValue) {
        onChange(self, newValue);
  });
}