Knockout.js“可见”调用异步函数 - 不工作

时间:2017-02-02 14:20:01

标签: javascript asynchronous knockout.js

我一直在努力理解异步,承诺等等,我认为我对它有基本的了解,但我没有得到我期望的结果。

我有一个HTML表格,其中包含以下内容:

<table data-bind="visible: viewPrincipal()">

viewPrincipal()是一个应该返回true或false的函数。如果viewPrincipal()只包含返回false或返回true,则它在最基本的级别上工作。但我要做的是调用异步函数从中获取true或false值。

function viewPrincipal() {
  console.log("Seeing if person is in principal group");
  return IsCurrentUserMemberOfGroup("Principal Members", function (isCurrentUserInGroup) {
    console.log(isCurrentUserInGroup);
    return isCurrentUserInGroup;
  });
}

console.log有效,并返回true或false,正如我所期望的那样。但我希望父viewPrincipal()函数返回true或false值,而我得到的只是“undefined”。

我理解为什么会发生这种情况 - IsCurrentUserMemberOfGroup()函数需要一些时间来完成 - 但我不知道如何修复它。我知道如何将函数链接在一起,但是当我尝试使用像knockout.js这样的东西来确定表是否可见时,我不知道如何链接。

有人可以帮忙吗?

2 个答案:

答案 0 :(得分:2)

最好的方法是使用可观察的bool,让你的a-sync函数改变它的值。让双向绑定的魔力完成剩下的工作。

实施例:JSFIDDLE

function vm() {
    this.viewPrincipal = ko.observable(false);
};

var vm = new vm();
ko.applyBindings(vm);

function fakeAsync() {
    setTimeout(() => {
        vm.viewPrincipal(true);
    }, 1500);
}
fakeAsync();

答案 1 :(得分:1)

我的方法有点迷失,但我会尽力帮助。

首先,请仔细考虑是否确实要在客户端实施访问控制。如果用户没有足够的权限,只是隐藏一个元素是非常危险的,因为(可能)敏感的内容仍然存在于DOM中,它仍然被下载,你所做的就是不显示它。即使是新手黑客也会找到一种方法来显示它 - 如果没有别的,他只能使用F12工具查看它。

其次,功能的三重嵌入真的是必要的吗?你有一个最外面的函数,它调用一个函数,然后调用提供的回调函数。您可以使用computed observables

清除此问题
function viewModel() {
    var self = this;

    var serverData = ko.observable(null);
    this.viewPrincipal = ko.computed(function() {
        var srvDataUnwrapped = serverData();    // access the inner value

        if (!srvDataUnwrapped) {
            return false;
        }

        // Do your decision logic here...

        // return false by default
        return false;
    });

    // Load the permission details from the server, this will set
    // a variable that the viewPrincipal depends on, this will allow
    // Knockout to use its dependency tracking magic and listen for changes.
    (function() {
        $.ajax(url, {
            // other config
            success: function (data) {
                serverData(data);
            }
        );
    })();
};

var vm = new viewModel();

然后在你看来:

<table data-bind="visible: viewPrincipal">

请注意,()observable处是否为observable,因此Knockout将知道如何使用它。

如果添加到现有代码中这似乎过于复杂,那么您只需定义一个function viewModel() { // other stuff ... this.viewPrincipal = ko.observable(false); // Call this wherever it fits your requirements, perhaps in an init function. function checkPrincipal() { IsCurrentUserMemberOfGroup("Principal Members", function (isCurrentUserInGroup) { viewPrincipal(isCurrentUserInGroup); }); }; }; ,然后在回调中设置该值:

<table data-bind="visible: viewPrincipal">

使用这种方法,标记将与前一个标记相同,即没有括号:

IsCurrentUserMemberOfGroup

这样做只会在传递给observable的回调中设置 observable 的内部值,并且因为Knockout能够跟踪HMap s的变化,价值变化将反映在用户界面中。

希望有所帮助。