knockout - 需要使用数组对象更新视图

时间:2016-07-14 12:58:31

标签: knockout.js

我有一个对象数组,其中每个对象都定义了我想要显示的特定模态的元素。 所以它就像。

var data = [{view1:"hello", view2:"world"}];

var viewModel = {
     currentView: ko.observable({})   // are objects observable?
};

然后当我加载模态时,我将对象从数组中取出。

var getDataForView = function (id) {
        var result = data.filter(function (obj) {
            return obj.Id == id;
        });
        return result;
    };

然后将该对象加载为当前视图。

var singleViewData = getDataForView(id);
viewModel.currentView(singleViewData);

该对象似乎没有更新?当我呼叫不同的意见。我在这里做错了什么,这样做的正确方法是什么?

3 个答案:

答案 0 :(得分:2)

getDataForView返回一个数组。此外,您提供的测试数据不包含任何具有Id属性的对象。

如果你解决了这些问题,一切都按预期工作:

var data = [{
  view1: "hello",
  Id: 0
}, {
  view2: "world",
  Id: 1
}];

var viewModel = {
  currentView: ko.observable({}) // are objects observable?
};

var getDataForView = function(id) {
  var result = data.filter(function(obj) {
    return obj.Id == id;
  });
  return result;
};

ko.applyBindings(viewModel);

var singleViewData = getDataForView(0)[0];
viewModel.currentView(singleViewData);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<div data-bind="with: currentView">
  <pre data-bind="text: JSON.stringify($data, null, 2)">

</pre>

</div>

如果您的浏览器支持允许,您也可以使用.filter()[0]而不是Array.prototype.find

答案 1 :(得分:1)

我会使用计算

var data = [{view1:"hello", view2:"world"}];

var viewModel = {
    views      : ko.observable( data ),
    currentId : ko.observable('view1')
};
viewModel.currentView = ko.computed( function(){
    var cid = viewModel.currentId();
    var views = viewModel.views();
    if( views.hasOwnProperty( cid ) ){
       return views[cid];
    } else {
       return "";
    }
} );

答案 2 :(得分:1)

我相信您的问题是关于为什么您的观点不会更新其中的值。这样做的原因是,虽然currentView是可观察的,但其中包含的数据是 NOT 可观察的。如果您想更新值&#39; hello&#39;和世界&#39;然后他们必须可观察。我确定你的例子有点做作,你的数据确实存在问题 - 但问题的答案是:

  • 如果您想要更新一个值,那么它需要是一个可观察的,或者它不会被更新。这意味着各个属性,而不仅仅是它们所属的对象。

&#13;
&#13;
var data = [{ id: 123, view: ko.observable("hello") },
            { id: 456, view: ko.observable("world") }];

var ViewModel = function() {
  var self = this;
  self.currentView = ko.observable() // anything can be observable
};

 var getDataForView = function(id) {
    var result = data.filter(function(obj) {
      return obj.id == id;
    });
    if (result.length === 0) 
      return; 
    return result[0].view();
  };

var vm = new ViewModel();
vm.currentView(getDataForView(456));
ko.applyBindings(vm);
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<input type="text" data-bind="textInput: currentView"/>
<br/>
<br/>
Current view: <b data-bind="text: currentView"></b>
&#13;
&#13;
&#13;