淘汰订阅:初始化还是更新?

时间:2013-11-28 15:22:57

标签: knockout.js

如果这是更新或初始化,我如何在订阅期间检查?

我有订阅者可以为数据库节省价值。加载值时我不需要它完成。我只需要在更新可观察值时才加载它们吗?

这就是我将数据加载到模型中的方法:

  ko.mapping.fromJS(dataJson, {}, PortfolioView);
  ko.applyBindings(PortfolioView, document.getElementById(containerId));

这就是我订阅者的方式:

   self.CompanyName = ko.observable();
   this.CompanyName.subscribe(function () {
      // This won't get called on init
      console.log("updated");
   }, this);

当页面加载时,我看到更新了。

然而,实际上我有大约20个变量。

1 个答案:

答案 0 :(得分:1)

你必须什么都不做。标准.subscribe函数不会在init上被触发。

试试吧。 Jsfiddle

function vm() {
    this.a = ko.observable("a");
    this.a.subscribe(function () {
        // This won't get called on init
        console.log("updated");
    }, this);
}

ko.applyBindings(new vm());

实际上,我在小提琴中展示的约束是value。如果您正在谈论自定义绑定,则会在specs中看到initupdate功能是分开的。


如果我们谈论计算的observable,据我所知,检查它是否为init的唯一方法是使用单独的变量跟踪第一个调用。这种方法很糟糕:如果这是你需要做的,你可能做错了。从上面的例子中,我们继续:

this._isInit = true;
this.b = ko.computed(function () {
    console.log("is init? " + this._isInit);
    if (this._isInit) this._isInit = false;
    return this.a();
}, this);

Fiddle


由于您已使用相关代码更新了问题,因此我可以加深答案。来自.fromJS的{​​{3}}:

  

[fromJs]自动为每个人创建可观察的属性   数据属性。

这不是你想要做的。您已经拥有您的observable和订阅它:调用.fromJS将更改它的值,导致订阅触发。让PortfolioView接受dataJson作为其构造函数的参数,然后重写您的代码:

function PortfolioView(data) {
    this.CompanyName = ko.observable(data.CompanyName);
    this.CompanyName.subscribe(function () {
        // This won't get called on init
        console.log("updated");
    }, this);
}

然后,调用以下代码将不会在页面加载时触发订阅。

ko.applyBindings(new PortfolioView(dataJson), document.getElementById(containerId));