Warm tip: This article is reproduced from serverfault.com, please click

javascript-剔除 Observable 到的数组绑定以查看分配值的延迟是否未发生

(javascript - knockout observable array binding to view when there is a delay in assigning value not happening)

发布于 2020-12-07 11:57:48

我有一个 Observable 到的 Observable 数组,其值分配在设定的时间值后发生变化,但是在视图中看不到这一点。有人可以告诉我我在哪里做错了吗?我希望输出显示

•GRE 1111•托福111

但它显示

•GRE2 222•托福2 22

jsFiddle链接:https://jsfiddle.net/4r37x9y5/

HTML:

console.clear();

function viewModel() { 

this.plans = ko.observableArray([]);
    
    var plans1 = [
        { id: 'GRE', count: '1111' },
        { id: 'TOEFL', count: '111' },
        ];
        
            var plans2 = [
        { id: 'GRE2', count: '222' },
        { id: 'TOEFL2', count: '22' },
        ];
        
        this.plans = plans2;
        //this.plans = plans1;
        
        setTimeout(function(){
        console.log("In timeout before assigning plans");
      this.plans = plans1;
      console.log(this.plans);
      }, 2000);     

}

ko.applyBindings(viewModel());
// The above line equals:
// viewModel(); // updates window object and returns null!
// ko.applyBindings(); // binds window object to body!
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>
<div class="panel panel-default">
    <ul data-bind="foreach: plans" class="list-group">
        <li class="list-group-item">
            <span data-bind="text: id"></span>
            <span data-bind="text: count"></span>
        </li>
    </ul>
</div>
Questioner
AMicrosoftVictim
Viewed
0
adiga 2020-12-07 20:30:55

这里有几个问题。正如你在评论中提到的那样,你没有将对象与 Observable 对象绑定。你只是在添加一个全局变量plans如果敲除无法在viewModel中找到属性,它将使用window对象的属性。这就是为什么它第一次起作用

  • 你需要更改viewModel为构造函数并用于new viewModel()创建对象或实例。
  • 应通过将 Observable 对象称为函数读取和更新 Observable 对象因此,this.plans(plans1)如果你设置this.plans = plans2,它将使用简单数组简单地覆盖 Observable 对象,而无需订阅者在属性更改时更新UI
  • 你需要使用正确的thisinside setTimeout通过在self = this外部创建变量或使用箭头函数作为回调

function viewModel() {
  this.plans = ko.observableArray([]);
  
  var plans1 = [{ id: "GRE", count: "1" }, { id: "TOEFL", count: "1" }];
  var plans2 = [{ id: "GRE2", count: "2" }, { id: "TOEFL2", count: "2" }];

  this.plans(plans2) // call it like a function

  setTimeout(() => {
    console.log("In timeout before assigning plans");
    this.plans(plans1)
  }, 2000);
}

ko.applyBindings(new viewModel()); // new keyword to create an object
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.2/knockout-min.js"></script>

<ul data-bind="foreach: plans">
  <li>
    <span data-bind="text: id"></span>
    <span data-bind="text: count"></span>
  </li>
</ul>