2

テンプレート全体のレンダリングが終了したときにコールバックを発生させる方法は KnockoutJS にありますか?

afterRender使用できるオプションがあることを理解しています:

"template: { name: 'Template', afterRender : myCallback}"

しかし、テスト ページでコールバックが 2 回発生します (foreach表示するデータのコレクションを使用しておらず、持っていません)。

私が求めているものに似た次の質問を見てきました。

テンプレートのレンダリング後の KnockoutJS bind イベント

しかし、その質問の答えは私を助けませんでした。

KO が検出した各要素の後だけでなく、テンプレート全体のレンダリングが終了した後に発生する Knockout のイベントはありますか?

編集:くそー、この質問を投稿するのを急いで、テンプレートをロードするためにこれを使用していることを忘れていました:

https://github.com/ifandelse/Knockout.js-External-Template-Engine

テンプレートは外部ファイルに保存されるため。

4

4 に答える 4

1

これをさらに説明する github のエントリを (すぐに) 見つけることができませんでしたが、2 回レンダリングされる理由はバグです。私の外部テンプレート エンジンのローカル コピーには、22 行目に "self" が追加されており、これで修正されました。

それ以外の

options.afterRender = function() {

これを使って

self.options.afterRender = function() {

また、NuGet のバージョンは古くなっているように見えることに注意してください。GitHub バージョンには、このバグ修正が既に含まれています。

于 2013-05-27T12:53:26.570 に答える
0

私は外部テンプレート(あなたと同じライブラリ)でノックアウトも学んでおり、私のものも2回起動しています。

その理由は、infuser が loadingTemplate をレンダリングするときに afterRender が 1 回起動し、次に実際の外部テンプレートが読み込まれるときに 1 回起動するためです。したがって、設定でオプションを設定したとしても:

infuser.defaults.useLoadingTemplate = false;

空のテンプレートを使用する場合を除いて、まだ 2 回起動します。これが意味することは、私がこれを行うことができるということです (私の afterRender が行うことは、テンプレートがロードされ、コンテンツに合わせてサイズ変更されると、モーダル ウィンドウを表示することだけです)。

二重イベントの発生を回避するためだけに非同期をオフにすることは、おそらく理想的ではありません。

テンプレート

<div data-bind="template: { name: template().name(), data: template().data(), afterRender: renderComplete }"></div>

モデルを見る

var renderComplete = function (params) {

  if (params.length > 0) {

     //Do my stuff here.

  }

};

より良い方法がある場合、または明らかに間違ったことをした場合は、お知らせください:)

于 2013-02-13T09:05:16.173 に答える
0

著者が作成した KO 用の別の AMD ライブラリを使用しています。

https://github.com/rniemeyer/knockout-amd-helpers

私のものは最もエレガントなソリューションではありませんが、うまくいきました。私がしたことは、setTimeout(callback,100) を使用してすべてのテンプレートに afterRender 呼び出しを追加することでした。コールバックは、解決するために延期された jQuery を設定します。deferred が解決されると、すべてのレンダリングが完了したことがわかり、コードを実行できるようになります。

// create a jQuery deferred
var dfd = $.Deferred();

// in my template call
afterRender: function () {

  // clear the timeout if it's still in play
  if (renderTimeoutId !== undefined) {
      clearTimeout(renderTimeoutId);
  }

  // create a new timeout and restart the clock
  renderTimeoutId = setTimeout(function () {
      dfd.resolve();
  }, 100);
}

// when my code is complete
dfd.done(function(){ /* after rendering code */});

これに対するより洗練された解決策に非常に興味があります。コードがタイムアウトに依存するのは本当に好きではありませんが、当時私が思いついたのはこれが最善でした。

于 2013-05-16T16:33:01.877 に答える