javascript – 有没有办法告诉敲门等待重新计算计算值,直到定义视图模型为止? - 代码日志

javascript – 有没有办法告诉敲门等待重新计算计算值,直到定义视图模型为止?

我有一个复杂的视图模型,它是几百行JavaScript代码,具有很好的可观察属性,计算的可观察属性,可计算的可观察属性和函数。所以管理这是一个很大的挑战。

我必须处理的一个令人讨厌的问题是,当您定义它时,计算的可观察值会立即正确计算。因此,使用在视图模型中尚未定义的变量,在定义可观察值的过程中会导致错误,指出该变量尚未定义。只是在文件的后面。

这是一个有创意的例子:

function ViewModel1​(args) {
    var self = this;

    self.firstName = ko.observable(args.firstName);
    self.lastName = ko.observable(args.lastName);
    self.fullName = ko.computed(function () {
        return self.firstName() + ' ' + self.lastName();
    });
}

function ViewModel2​(args) {
    var self = this;

    self.fullName = ko.computed(function () {
        // uh oh, where's firstName?
        return self.firstName() + ' ' + self.lastName();
    });
    self.firstName = ko.observable(args.firstName);
    self.lastName = ko.observable(args.lastName);
}

使用ViewModel1将无任何问题。在定义fullName的时候,定义firstName和lastName,以便它按预期工作。使用ViewModel2将无法正常工作。计算函数中将出现错误,说明firstName未定义。

现在我一直在做的是确保在定义所有因变量后定义所有计算的可观察值。这样做的问题是,在这样做的时候,事情被定义在看似随机的地方,当我宁愿把相关的变量定义在一起时。

我想出的一个很好的解决方案是将“初始化”可观察集定义为true,并使所有计算的可观察值都测试是否仍然初始化,并在不进行计算并返回值时进行测试。这样,就不会进行访问当前未定义的变量的尝试。

function ViewModel3(args) {
    var self = this;
    var initializing = ko.observable(true);

    self.fullName = ko.computed(function () {
        if (!initializing()) {
            return self.firstName() + ' ' + self.lastName();
        }
    });
    self.firstName = ko.observable(args.firstName);
    self.lastName = ko.observable(args.lastName);

    initializing(false);
}

但是,在我的情况下这不会很实际。我有很多计算的可观测量,所以这样做在所有这些将使它非常blo肿,记住我有很多这些。调节它似乎没有什么不同。

在尝试计算计算的可观察值的值之前有没有办法告诉淘汰赛等待?还是有更好的方法来构造我的代码来处理这个问题?

我可以做一些帮助函数来管理初始化逻辑,但是我仍然需要更改所有计算的可观察定义。我想我可以通过猴子补丁淘汰来添加这个初始化逻辑,因为我不知道敲门机有这样的选择,我可能会这样做。我以前看过计算的可观察的来源,但我不知道其他地方是否有一个设置。

jsfiddle demo

计算的可观察值接受一个deferEvaluation选项,阻止初始评估发生,直到某些实际尝试检索计算的值。

你会定义如下:

self.fullName = ko.computed({
   read: function() {
       return self.firstName() + " " + self.lastName();
   },
   deferEvaluation: true
});

只是为了完整,你也可以这样指定:

this.fullName = ko.computed(function() {
       return this.firstName() + " " + this.lastName();
 }, this, { deferEvaluation: true });

或者你可以包装它像:

ko.deferredComputed = function(evaluatorOrOptions, target, options) {
   options = options || {};

   if (typeof evaluatorOrOptions == "object") {
       evaluatorOrOptions.deferEvaluation = true;   
   } else {
       options.deferEvaluation = true;
   }

   return ko.computed(evaluatorOrOptions, target, options);
};
http://stackoverflow.com/questions/11569341/is-there-a-way-to-tell-knockout-to-wait-to-recalculate-computed-values-until-aft

本站文章除注明转载外,均为本站原创或编译
转载请明显位置注明出处:javascript – 有没有办法告诉敲门等待重新计算计算值,直到定义视图模型为止?