如何在knockoutjs中获得ko.computed或ko.observable底层函数?

时间:2014-07-10 16:41:21

标签: javascript knockout.js observable

我正在viewModel上创建ko.observable,以控制验证摘要的可见性。

PageObj.bcInStoreActivityWithVisits.IsValidationVisible = ko.observable(PageObj.bcInStoreVisit()[0].Fields.ErrorState() == "Active" || getErrorState(PageObj.bcInStoreVisit()[0].Fields.Id()) == "Active");

有一个按钮finish audit,它将底层存储中的值设置为bcInStoreVisit我已经测试过设置机制的活动状态,并且工作正常。

错误状态变量PageObj.bcInStoreVisit()[0].Fields.ErrorState()在后​​续访问页面时也能正常工作。

现在奇怪的部分:在刷新页面之前验证值已经激活如果我从chrome console PageObj.bcInStoreActivityWithVisits.IsValidationVisible调用它返回false但是如果我调用底层javascript ko.observable(PageObj.bcInStoreVisit()[0].Fields.ErrorState() == "Active" || getErrorState(PageObj.bcInStoreVisit()[0].Fields.Id()) == "Active"它返回truegetErrorState(PageObj.bcInStoreVisit()[0].Fields.Id())已放入其中,以便立即显示验证(下面的屏幕截图)。

enter image description here

这意味着PageObj.bcInStoreActivityWithVisits.IsValidationVisible订阅了其他内容。

有没有办法检查ko.observable下订阅的基础javascript是什么?
换句话说,如何从ko.observable(PageObj.bcInStoreVisit()[0].Fields.ErrorState() == "Active" || getErrorState(PageObj.bcInStoreVisit()[0].Fields.Id()) == "Active"获取PageObj.bcInStoreActivityWithVisits.IsValidationVisible

更新:我查看PageObj.bcInStoreActivityWithVisits.IsValidationVisible._subscribers change个事件有3个,它们看起来都相同,但没有一个看起来像(PageObj.bcInStoreVisit()[0].Fields.ErrorState() == "Active" || getErrorState(PageObj.bcInStoreVisit()[0].Fields.Id()) == "Active"

更新2 :事件触发序列。

if (hasAllDatasources) {
            if (isPopulatingForFirstTime) {
                $(bc).OnTheMoveBCTrigger('OnPreUIUpdate', [promises]);
                $.when.apply($, promises).then(function () {
                    var eventPromise = $(onTheMove.PageDataRoles).OnTheMoveTrigger('OnPreRender');
                        eventPromise.then(function () {
                            onTheMove.applyKOBindings();
                            invokeMethodsFromQueryString();
                            $(onTheMove.PageDataRoles).OnTheMoveTrigger('OnRender');
                        });
                });
            }
        }

2 个答案:

答案 0 :(得分:1)

  

这意味着   订阅了PageObj.bcInStoreActivityWithVisits.IsValidationVisible   别的什么。

我认为你误解了一个可观察者是什么。 IsValidationVisible未订阅任何内容。相反,作为一个可观察的,其他东西可以订阅它。

让我们看一个更简单的例子:

// 1. Create foo and give it a value of "Hello"
var foo = ko.observable("Hello");

// 2. Get the value of foo and assign it to bar
var bar = ko.observable(foo());

// 3. Get the value of foo and assign it to baz
var tmp = foo();
var baz = ko.observable(tmp);    

请注意#2和#3正在做同样的事情。另请注意,在所有这3个示例中,没有任何内容订阅任何其他内容。

让我们改变foo,看看会发生什么

foo("Goodbye");
// After that, foo() will return "Goodbye"
// and bar() will return "Hello" - bar was set to "Hello" earlier and hasn't changed
// and baz() will return "Hello" - baz was set to "Hello" earlier and hasn't changed

所以你想订阅吗?以下是我们如何订阅某些内容:

var bat = ko.computed(function() {
  return foo() + " World!";
});

// If you call bat(), you'll see "Hello World!"

// Let's change foo
foo("Adios");

// Now if you call bat(), you'll see "Adios World!"

使用您的代码,您可以设置IsValidationVisible以通过创建这样的计算机来自动更新其中的observable:

PageObj.bcInStoreActivityWithVisits.IsValidationVisible = ko.computed(function() {
  return PageObj.bcInStoreVisit()[0].Fields.ErrorState() == "Active" ||
    getErrorState(PageObj.bcInStoreVisit()[0].Fields.Id()) == "Active";
});

答案 1 :(得分:1)

我仔细查看了屏幕截图中的代码,我认为我发现了另一个问题。我会减少代码,试着让它更简洁。

$(inStoreActivity).on('OnPreUIUpdate', function() {
  PageObj.IsAllRequiredActivitiesDone = ko.computed(function() { ... });
  PageObj.IsAllOptionalActivitiesDone = ko.computed(function() { ... });

  PageObj.IsValidationVisible = ko.observable(...big calculation...)

});

以下是我所看到的:

  1. 在其他地方,您最初在PageObj对象上创建了3个变量作为computed / observables(IsAllRequiredActivitiesDone, IsAllOptionalActivitiesDone, IsValidationVisible
  2. 在其他地方,您调用ko.applyBindings(...)将DOM绑定到PageObj(以及PageObj中的所有内容)
  3. 当OnPreUIUpdate事件触发时,您正在尝试更新这三件事,如上面的代码所示
  4. (如果我对第1点和第2点的假设错了,请提供代码告诉我我缺少的东西)

    首先,让我们看看IsValidationVisible可观察对象。

    您成功创建了observable,为其赋值,并将其绑定到DOM。但是,您没有以正确的方式更新observable。因为您在此事件处理程序中调用ko.observable(...),所以每次事件触发时都会创建一个新的observable。但是,这些新的observable都没有绑定到DOM(当你调用ko.applyBindings时它们不存在)。

    以下是在事件处理程序中正确更新IsValidationVisible的方法:

    // This is good - this is how to update an observable
    PageObj.IsValidationVisible(...big calculation...);
    
    // This is bad - DON'T UPDATE AN OBSERVABLE THIS WAY
    PageObj.IsValidationVisible = ko.observable(...big calculation...)
    

    其次,让我们考虑一下计算出的属性。

    计算的想法是,只要计算更新使用了可观察量,它就会自动运行。所以你只需定义一次计算就完成了。

    你在代码中所做的是每次事件触发时创建一个新的计算,并且,就像我上面提到的关于上面的observable一样,只有你创建的初始计算将被绑定到DOM,所以新的你创建的计算机没有做任何事情。