KnockoutJS Observable正在适当反弹,但是调用给出一个空字符串?

时间:2017-09-06 05:21:43

标签: javascript knockout.js

所以我有一个基于名为ko.observable的{​​{1}}更新的部分,见下文:

toClicked

<div id="longInfoWindow"> <div id="longInfo_goBack"><span class="fa fa-arrow-left"></span> Go Back</div> <div id="location_mainInfo"> <h1 id="location_title" data-bind="text: toClicked.title">Title</h1> <h2 id="location_address" data-bind="text: toClicked.address">Address</h2> <h6 class="location_latlng">LAT: <span data-bind="text: toClicked.lat">LATITUDE</span></h6> <h6 class="location_latlng">LNG: <span data-bind="text: toClicked.lng">LONGITUDE</span></h6> <p id="location_description" data-bind="text: toClicked.content"> Empty </p> </div> </div> 通过toClicked for-each进行数据绑定,从ul传递一些信息,因此这些数据会不断变化 - 这就是点击功能看起来像在viewmodel中。

observableArray

出于某种原因,我可以调用任何var viewModel = { // Nav open and close via knockoutjs self : this, userQuery : ko.observable(''), toClicked : ko.observable({}), logClick : function(clicked){ var toClicked = ko.observable({}); toClicked().title = clicked.title; toClicked().lat = clicked.lat; toClicked().lng = clicked.lng; toClicked().placeID = clicked.placeID; toClicked().address = clicked.address; toClicked().content = clicked.content; return toClicked(); } }; // at the end of the document... ko.applyBindings(viewModel); 参数,例如toClicked,并获得正确的输出。但我无法在toClicked.title位代码中绑定任何内容,它会删除带有空字符串的填充文本。是否有一些我在Knockout中缺少的东西让它无法正确更新?

作为旁注,我已经尝试将数据条设置为longInfoWindow而没有任何乐趣。还尝试了viewModel.toClicked.title$root。或者返回未定义或给出相同的结果。

2 个答案:

答案 0 :(得分:1)

您需要更改toClicked的访问方式。鉴于它是一个可观察的,它必须使用toClicked().property之类的语法访问属性。另一个问题是,在设置属性之前,应将toClicked指定为对象。

此外,由于clicked是一个数组,因此应该通过索引访问它,例如clicked[0].title

请注意在函数self.toClicked.valueHasMutated();中使用logClick。它告诉视图模型可观察变量toClicked具有一些可能已更改的不可观察属性。结果,视图模型被更新。你应该避免过度使用它。

var viewModel = function() {
  // Nav open and close via knockoutjs
  var self = this;

  self.test =  ko.observable('text');

  self.userQuery = ko.observable('');
  self.toClicked = ko.observable({});

  self.markers = ko.observableArray([
    { title: 'Eagle River Airport', lat: 45.934099, lng: -89.261834, placeID: 'ChIJdSZITVA2VE0RDqqRxn-Kjgw', content: 'This is the Eagle River Airport. Visit us for fly-ins!' }
  ]);

  self.logClick = function(clicked) {
    // var toClicked = ko.observable({});
    self.toClicked().title = clicked[0].title;
    self.toClicked().lat = clicked[0].lat;
    self.toClicked().lng = clicked[0].lng;
    self.toClicked().placeID = clicked[0].placeID;
    self.toClicked().address = clicked[0].address;
    self.toClicked().content = clicked[0].content;
    self.toClicked.valueHasMutated();
    return self.toClicked();
  };
};

// at the end of the document...
var vm = new viewModel();
ko.applyBindings(vm);
var markers = vm.markers();
vm.logClick(markers);

您的视图模型也必须稍微改变。请注意()之后的toClicked括号,它们用于访问可观察对象的属性。

<div id="longInfoWindow">
 <div id="longInfo_goBack"><span class="fa fa-arrow-left"></span> Go Back</div>
 <div id="location_mainInfo">
    <h1 id="location_title" data-bind="text: toClicked().title">Title</h1>
    <h2 id="location_address" data-bind="text: toClicked().address">Address</h2>
    <h6 class="location_latlng">LAT: <span data-bind="text: toClicked().lat">LATITUDE</span></h6>
    <h6 class="location_latlng">LNG: <span data-bind="text: toClicked().lng">LONGITUDE</span></h6>
    <p id="location_description" data-bind="text: toClicked().content">
       Empty
    </p>
 </div>

我还建议您不要直接在toClicked内访问logClick,而是使用类似self.toClicked的内容来避免含糊不清。请参阅this

这是工作小提琴:https://jsfiddle.net/Nisarg0/hx0q6tt6/13/

答案 1 :(得分:0)

不必使用valueHasMutated的更明显的方法是直接分配给observable:

  self.logClick = function(clicked) {
    self.toClicked({ 
        lat: clicked[0].lat, 
        lng: clicked[0].lng, 
        placeID: clicked[0].placeID, 
        adress: clicked[0].address,
        content: clicked[0].content
    }); 
  };

使用knockout时,通常不需要使用valueHasMutated。此外,无需从单击处理程序返回observable。在您的绑定中,您需要访问如下所述的属性:

<h1 id="location_title" data-bind="text: toClicked().title">Title</h1>

每当toClicked更改时,Knockout将自动更新标题。