2017-02-02 31 views
1

私は非同期や約束などを理解しようとしていましたが、基本的な理解はしていますが、期待した結果が得られません。Knockout.js非同期呼び出し関数が動作しない

私は次のように、HTMLのテーブルを持っている:

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

viewPrincipal()がtrueまたはfalseを返すべき関数です。 viewPrincipal()が単にfalseを返すかtrueを返すだけであれば、これは最も基本的なレベルで動作します。しかし、私がしようとしているのは、そこから真偽値を得る非同期関数を呼び出すことです。

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()関数がその真偽値を返すことを望み、私が得るのは "未定義"です。

私はIsCurrentUserMemberOfGroup()関数が完了するのに少し時間がかかりますが、なぜこれが起こっているのか理解していますが、修正方法はわかりません。私は関数を連鎖させる方法を知っていますが、knockout.jsのようなものを使用して表を表示するかどうかを判断しようとしているとき、どうやって連鎖するのか分かりません。

誰でも手助けできますか?

答えて

1

私はあなたのアプローチで失われたビットが、私は助けしようとするでしょう。

まず、クライアント側で実際にアクセス制御を実装するかどうかを考えてください。ユーザーが十分な権利を持っていない場合、単に要素を隠すだけで、危険な状態になることがあります。機密性の高いコンテンツはまだDOMに残っており、まだダウンロードされています。初心者のハッカーであっても、それを表示する方法を見つけることができます。もし何もなければ、F12ツールを使って簡単に見ることができます。

第2に、関数の三重埋め込みが本当に必要なのでしょうか?最も外側にある関数があり、関数を呼び出すと、それは指定されたコールバックを呼び出します。あなたのビューで、その後

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(); 

をして:あなたはcomputed observablesを使用してこれを片付けることができ

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

ノートここ()年代には、それはノックアウトを使用する方法を知っているので、observableであれば不足それ。これはあなたの既存のコードに追加するには過度に複雑ようであれば、あなたは、単に代わりobservableを定義し、コールバック内でその値を設定することができ

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); 
     }); 
    }; 
}; 

このアプローチでは、マークアップでしょうこの方法は、単にコールバックY内側観察の内側値を設定し、それを行う

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

:括弧なしの前の、すなわち、と同一でありますouはIsCurrentUserMemberOfGroupに、ノックアウトはobservableの変更を追跡できるため、値の変更はUIに反映されます。

希望に役立ちます。

+0

ありがとう!これは、ここでの他のコメントと一緒に、私にこの全部を理解させるのに非常に役立ちました。私はセキュリティ上の問題があると認識していますが、(幸いにも私にとって)この変更の要件は、ほとんどの人から特定のデータを隠すのではなく、ほとんどの人にとってフォームを小さくして短くすることです。私は今それで大丈夫です。 –

2

観測可能なブールを使用して、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

ありがとうございました!これは本当に私が何をすべきかを理解するのに役立ちました。 –

関連する問題