1

afterRenderイベントのAJAX呼び出しによってトリガーされたKnockoutテンプレートによって作成された要素へのバインドに問題があります。このフィドルでわかるように、結果は適切にレンダリングされますが、afterRenderイベントハンドラーでは要素はまだ使用できません。

質問...

  • afterRenderイベントハンドラーの実行時にテンプレートがレンダリングされていないように見えるため、テンプレートはどのように適切にレンダリングされますか?

  • AJAX呼び出しが結果に影響するのはなぜですか?AJAX呼び出しの上の行のコメントを外すと、テンプレート要素はafterRenderイベントで使用できます。

これがコードです...

HTML

<div id="plugin" data-bind="template: { name: 'fooTemplate', data: $data, afterRender: postProcess }"></div>
<br />
<br />
<hr />
<div id="results"></div>

<script type="text/html" id="fooTemplate">
    <div data-bind="foreach: items()">
        <span data-bind="text: displayText"></span>
    </div>
</script>

JAVASCRIPT

var data = {
    items: [{
        displayText: 'Name',
    }, {
        displayText: 'Last Login Date',
    }, {
        displayText: 'Email',
    }]
};

function DataModel() {
    var self = this;
    self.items = ko.observableArray([]);
    self.data = ko.dependentObservable(function () {
        //self.items(data.items);//   <<== UNCOMMENT THIS LINE AND THE postProcess FUNCTION SHOWS FULLY RENDERED DOM
        $.ajax({
            url: '/some/path',
            error: function () {
                self.items(data.items);
            }
        });
    });

    postProcess = function () {
        $('#results').text($('#plugin').html());
    }
}

dataModel = new DataModel();
ko.applyBindings(dataModel);

1つの注意...フィドルは偽のアドレスにAJAX呼び出しを行います。これは、Fiddleにサーバーの依存関係がないためです。errorプロパティを利用して、テンプレートを実行するデータを変更します。ただし、私の開発環境では、有効なURLを呼び出すと、フィドルに表示されるのと同じ結果が得られます。また、サーバーから返されたデータを使用してテンプレートをロードしていません。むしろ、フィドルは上部に静的に定義されたデータソースを使用します(これも問題をデモするためです)。

4

1 に答える 1

1

あなたの例を見ると、非同期の問題が発生しています。

$.ajax 呼び出しなしでフローがどのように機能するかを次に示します。

  1. dependentObservable が起動して値を更新します
  2. self.items は新しい値で更新されます
  3. テンプレートがレンダリングされます
  4. postProcess メソッドが呼び出され、すべて問題ないように見えます。

しかし、$.ajax 呼び出しでは、完了 (およびエラー) メソッドがコールバックであるため、フローが変わります。

  1. dependentObservable (代わりに ko.computed を使用してください!) が起動して値を更新します
  2. サーバーに対して $.ajax 呼び出しが行われます。
  3. 完了 (またはエラー) コールバックは、完了したときのためにキューに入れられます。
  4. テンプレートがレンダリングされます
  5. postProcess メソッドが呼び出されますが、self.items はまだ空です。
  6. サーバーが応答して self.items を更新すると、done コールバックが発生します。
  7. レンダリングされたテンプレートはまだビューモデルにバインドされているため、レンダリングされたテンプレートは更新されます。

最も簡単な修正は、依存するオブザーバブルから ajax 呼び出しを引き出して、コメントアウトした状況を許可することだと思います。

于 2013-02-18T19:08:40.283 に答える