knockout.js 当 AJAX 参与进来的时候,就像事件已经发生了一样,当事件还没有发生的时候,就像事件已经发生了一样,

5q4ezhmt  于 2023-03-23  发布在  其他
关注(0)|答案(1)|浏览(144)

我使用<details><summary>元素作为一个快速的“ accordion ”,当用户通过单击摘要来展开元素时,可以获取数据。这是一个按需获取数据的场景。当我在docReady初始化函数中“手动”使用测试数据填充淘汰的可观察数组时,它可以工作。但是如果我使用 AJAX (window.fetch),获取数据以响应页面上其他地方的用户操作,knockout是在尝试在数组被填充之前,甚至在它被初始化之前,在数组上执行forEach绑定。
在下面的标记中,details元素缺少open属性,因此默认情况下它是关闭的。元素打开触发toggle事件,其处理程序获取数据以填充“edlns”数组。knockout的行为就像details.toggle事件已经触发一样,而实际上它还没有触发。

<div id="TitlesContainer" data-bind="{visible:TitlesModel.showTitlesContainer, foreach: TitlesModel.Titles}">
        <details tabindex="-1" data-bind="event:{toggle: function(){TitlesModel.FetchPassages}}">
            <summary data-bind="text: name + ' (' + cat + ') [' + hits + ']'"></summary>
            <div class="hits" data-bind="foreach: edlns">
                <div class="passage-container">
                    <p class="edln" data-bind="text: '(' + edln + ')' "></p>
                    <p class="passage" data-bind="{html: text}"></p>
                </div>

            </div>
        </details>

    </div>
o8x7eapl

o8x7eapl1#

不幸的是,我无法在本地使用stackoverflow代码段复制您的问题。但这里有一个代码段,其他人可能可以使用它作为起点来帮助。
我怀疑这将与敲除初始化变量,然后级联更新到其他observable有关。我遇到过这样的问题,尽管与事件绑定无关,我引入了一个observable标志,当加载时设置为true,当完成时设置为false。这允许我在加载视图/视图模型期间运行的函数中添加对标志的检查。

function Edln() {
  var self = this;
  self.edln = ko.observable();
  self.text = ko.observable();
}

function Title(data) {
  var self = this;
  let edln = new Edln();
  edln.edln(`Test ${data.hits}`);
  edln.text(`<strong>${data.name}<strong>`);
  
  self.name = ko.observable(data.name || '');
  self.cat = ko.observable(data.cat || '');
  self.hits = ko.observable(data.hits || 0);
  self.edlns = ko.observableArray([edln]);
  self.summary = ko.pureComputed(function(){
    return  `${self.name()} (${self.cat()}) [${self.hits()}]`
  });
}

function TitlesModel() {
  var self = this;
  self.showTitlesContainer = ko.observable(true);
  self.Titles = ko.observable([])
  self.FetchPassages = function(item) {
    console.log(`fetch passages ${item.name()}`);
  }
  let i = 0;
  let arr = [];
  for (i = 0; i < 5; i++) {
    var title = new Title({
      name: `Title Name ${i}`,
      cat: `Some cat ${i}`,
      hits: i
    });
    arr.push(title);
    self.Titles(arr);
  }

}

function ViewModel() {
  var self = this;
  self.TitlesModel = new TitlesModel();
}
var vm = new ViewModel();
ko.applyBindings(vm);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div id="TitlesContainer" data-bind="{visible:TitlesModel.showTitlesContainer, foreach: TitlesModel.Titles}">
  <details tabindex="-1" data-bind="event:{toggle: function(){$root.TitlesModel.FetchPassages($data);}}">
    <summary data-bind="text:summary"></summary>
    <div class="hits" data-bind="foreach: edlns">
      <div class="passage-container">
        <p class="edln" data-bind="text: '(' + edln() + ')' "></p>
        <p class="passage" data-bind="{html: text}"></p>
      </div>
    </div>
  </details>
</div>

相关问题