4

ASP .NET MVC アプリケーションがあり、さらに Knockout 2.0.0 を使用しています。ノックアウトを使用してページにレンダリングしたい部分ビューを作成しました。パーシャルは Knockout foreach ステートメント内でレンダリングする必要があります。ノックアウト HTML バインディングを機能させることができないため、現在、ハックを使用して JQuery を使用して div に html を配置しています。

このページには多くの html があるため、すべてのソース コードを投稿することはできません。そのため、関連するコードを投稿してみます。

<div data-bind="foreach:issues">
    @* SNIP - A lot of other html here*@
    <div id="myPartialDiv" data-bind="html: $parent.getHtml(issueId())">
    </div>  
</div>

さらに下には、KO View Model に次の JavaScript 関数があります (ハックをコメントアウトし、HTML を返すコードを含めました)。

   var getHtml = function (issueId) {
              var baseUrl = '@Url.Action("GetHtmlAction","MyController")';
              $.ajax(
                {
                    type: "POST",
                    url: baseUrl,
                    data: "&issueId=" + issueId,
                    success: function (data) {
                        //$('#mypartialDiv').html(data);                          
                        return data;
                    },
                    error: function (req, status, error) {
                        //$('#myPartialDiv').html('Something went wrong.');
                        return 'Something went wrong.'
                    },
                    dataType: "text"
                });
         }

上記のコードでは、ページにレンダリングされるデータはありません。Chrome デバッグ ツールを使用すると、javascript エラーが発生していないことがわかります。ノックアウトは、div の html を getHtml 関数から返された結果にバインドしていないだけです。

私は何を間違っていますか?

ありがとう

4

2 に答える 2

4

Miroslav Popovic が説明しているように、問題は AJAX リクエストが非同期であるため、return dataが無視され、 への呼び出しからの戻り値がないことですgetHtml

非同期の HTML 読み込みを処理するカスタム バインディングを使用することをお勧めします (実際の例をここに載せました)。

これは、asyncHtml に 2 つのパラメーターを受け取ることによって機能します。最終パラメーター (およびその他のパラメーター) として成功コールバックを受け取る関数と、その関数に渡す必要があるパラメーターの配列です。

<div id="myPartialDiv" data-bind="asyncHtml: { source: getHtml, params: [123] }">Loading...</div>

次に、カスタム バインディングはこれらの値を取得し、渡されたパラメーターにカスタム コールバックを連結して、指定された関数を呼び出します。

ko.bindingHandlers.asyncHtml = {
    init: function(element, valueAccessor) {
        var value = ko.utils.unwrapObservable(valueAccessor());
        var parameters = value.params.concat([function(data) {
           $(element).html(data); 
        }]);
        value.source.apply(null, parameters);
    }
};

最後に、ビュー モデルの HTML 取得メソッドを再実装して、POST 呼び出しを行い、新しい成功ハンドラーを呼び出すことができます。

var ViewModel = function() {
    this.getHtml = function(issueId, callback) {
        $.ajax(
            {
                type: "POST",
                url: "/echo/html/",
                data: {
                        html: "<p>server response " + issueId + "</p>",
                        delay: 1
                    },
                success: callback,
                dataType: "text"
            });            
    };
};

注: この例では、jsFiddle を使用しechoてランダムな応答をポスト バックしています。

于 2012-06-12T10:10:28.417 に答える
3

$.ajax非同期呼び出しです。これを呼び出すと、実行は関数内の次のステートメントに進みgetHtmlます。これが最後のステートメントであるため、getHtml関数はを返しundefinedます。

あなたについてreturn data;...このリターンは成功コールバック関数内にあります。データは、親関数ではなく、そのgetHtml関数の結果になります。その上、getHtmlすでに完成しています。それから結果を返すことはできません。

ビューモデルhtmlにと呼ばれる監視可能なプロパティを設定し、関数をトリガーする他の手段getHtml(ボタンのクリック、他の成功コールバック、issueIdプロパティの変更...)を見つけて、'html'プロパティ値を設定するのはどうですか。 。次に、そのプロパティにデータバインドするだけですdata-bind="html: html"

于 2012-06-12T09:42:12.143 に答える