Data binding 敲除可见绑定失败

Data binding 敲除可见绑定失败,data-binding,knockout.js,single-page-application,Data Binding,Knockout.js,Single Page Application,我试图根据用户是否登录,使某些按钮不可见,为此我做了如下操作: 我有一个名为authmodule的模块,其编码如下: define(function () { var loggedIn = ko.observable(false); // tried without observable too. var updateLoginStatus = function () { // call the webapi using ajax and intercept the 401

我试图根据用户是否登录,使某些按钮不可见,为此我做了如下操作:

我有一个名为authmodule的模块,其编码如下:

define(function () {

var loggedIn = ko.observable(false);  // tried without observable too.

var updateLoginStatus = function () {
    // call the webapi using ajax and intercept the 401
    // if error is 401 set set loggedIn to false and
    // true otherwise.

    // set ajax call
    var options = {
        url: '/breeze/breeze/MicCheck123',
        type: 'GET',
        dataType: 'json'
    };

    // make call
    return $.ajax(options)
        .then(function (data) {
            loggedIn(true);
        })
        .fail(function (jqXhr, textStatus) {
            if (jqXhr.status == 401 || jqXhr.status == 404) {
                loggedIn(false);
            }
        });
};

// my ko.computed used in html to do visible binding
var isUserLoggedIn = ko.computed(function () {
    updateLoginStatus();
    return loggedIn;
});

var authmodule = {
    isUserLoggedIn: isUserLoggedIn,
    updateLoginStatus: updateLoginStatus
};

return authmodule;
});
我现在需要在我的shell.js中使用这个authmodule,并从viewmodle返回它,如下所示

define(['durandal/system',
    'services/logger',
    'durandal/plugins/router',
    'config',
    'services/authmodule'],
function (system, logger, router, config, authmodule) {

    var shell = {
        activate: activate,
        authmodule: authmodule,
        router: router
    };
    return shell;

    function activate() {
        return boot();
    }

    function boot() {
        router.map(config.routes);
        return router.activate(config.startModule);
    }
}
);
对应的shell.js的html如下所示

    <div class="navbar-inner navbar-secondary">
    <div class="btn-group">
        <!-- ko foreach: router.visibleRoutes -->
        <a data-bind="attr: { href: hash },
                      css: { active: isActive },
                      html: caption,
                      visible: $parent.authmodule.isUserLoggedIn"
           class="btn btn-info"></a>
        <!-- /ko -->
    </div>
    </div>

因为我有四条可见的路径,当ajax成功时,我希望在顶部功能区中看到4个按钮,当ajax失败时,我希望看不到任何按钮,但无论ajax结果如何,这似乎都不起作用

有人能帮我确定我到底错过了什么吗

我已经看过了


我认为您不需要isUserLoggedIn属性

因此,在按钮绑定中

visible: $parent.authmodule.isUserLoggedIn

并在主视图模型中替换:

var isUserLoggedIn = ko.computed(function () {
    updateLoginStatus();
    return loggedIn;
});
作者:


我希望它能有所帮助。

在ko.computed函数中,您需要调用observable(这是ko在重新计算计算值时知道的方式),如

然后,当可观测值发生变化时,计算值也将被更新


可能在您的示例中,ajax调用只应运行一次,而不应在计算机内部运行。

您确定$parent会为您提供正确的上下文吗非常感谢,先生,这很有效,非常感谢。我想我需要坐下来好好读一读关于淘汰赛的书,而不是简单地到处读一些博客,然后尝试一些事情。@indichimp:不客气。你可以看看这篇文章马塞洛谢谢你的回复,我试过了,它确实有效。我把这当作答案。上面@Damien提出的“订阅”解决方案也能起作用,但我想这不是使用订阅的方式。我觉得这个答案更正确。我必须说,您不应该使用computed作为事件处理程序。想象一下,如果将3个元素绑定到isUserLoggedIn,那么计算和updateLogStatus将被调用3次。但是,如果您希望仅在loggedIn发生更改时调用updateLoginStatus函数,则需要订阅属性loggedIn。这就是subcribe函数的目的(当属性发生更改时会得到通知)。
var isUserLoggedIn = ko.computed(function () {
    updateLoginStatus();
    return loggedIn;
});
loggedIn.subscribe(updateLoginStatus);
return loggedIn();