afterRender
はテンプレートバインディングで動作しますが、テンプレートをコンポーネントに変換した後、afterRender
を使用する方法はないようです。 afterRender
を使用するコンポーネントの例を探してみましたが、何も見つかりません。
上記の投稿どおりにメソッドを動作させることができませんでした。しかし、git issueリストに回避策が見つかりました。カスタムKOバインディングは必要ありません。
コンポーネントテンプレートhtmlまたはコードの文字列に次の行を追加します。
<span data-bind="template: { afterRender: init }"></span>
次に、モジュール/ viewModelでinit関数を作成します。
this.init = function() {
Do cool DOM stuff here.
}
または、viewModel構造に応じて:
viewModel: function(params) {
return {
init: function () {
}
};
},
魅力のように機能します。動作例はこちら
http://jsfiddle.net/gLcfxkv6/1/
ノックアウトgitのスレッドはこちら: https://github.com/knockout/knockout/issues/15
回避策を提供してくれたgitのヴァンプに感謝します。
ここでの秘密は http://knockoutjs.com/documentation/custom-bindings.html
ko.bindingHandlers.myCustomBinding = {
init: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called when the binding is first applied to an element
// Set up any initial state, event handlers, etc. here
if (bindingContext.$data.init) bindingContext.$data.init(element, valueAccessor, allBindings, viewModel, bindingContext);
},
update: function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// This will be called once when the binding is first applied to an element,
// and again whenever any observables/computeds that are accessed change
// Update the DOM element based on the supplied values here.
if (bindingContext.$data.update) bindingContext.$data.update(element, valueAccessor, allBindings, viewModel, bindingContext);
}
};
コンポーネントテンプレートで次のようにします
<div class="row-fluid" data-bind="myCustomBinding: 'someValue'">
そして、コンポーネントviewModelにinitおよび/またはupdateを実装するだけです。例えば:
constructor.prototype.init = function(element, valueAccessor, allBindings, viewModel, bindingContext) {
// All the buttons in the buttons group need the same name,
// but they all need distinct ids. We use timestamps because
// as components, the names and ids should be distinct across
// multiple instances of each component.
var timeStamp = new Date().getTime();
$('input:radio').attr('name', timeStamp).button();
$('input:radio:eq(0)').attr('id', timeStamp+1);
$('input:radio:eq(1)').attr('id', timeStamp+2);
$('input:radio:eq(2)').attr('id', timeStamp+3);
// Initialize the number-picker
$('input[name="number-picker"]').TouchSpin();
};
Knockoutのドキュメントは、この非常に便利なケースを指摘することで改善できます。また、これは非常に便利なバインディングです。たとえば、「init」と「update」の標準バインディングが必要です。たとえば、
<div data-bind="init: 'someValue'">
異なるコンポーネントを切り替えた後、コンポーネントのDOM要素にアクセスする必要がありました。コンポーネントに存在しない「afterRender」バインディングを使用したいと思っていました。
Javascript setTimeoutでそれを解決し、KOに最初にレンダリングを行わせ、その後コードを実際にキューに入れました。
HTML:
<div data-bind="component: compName"></div>
コンポーネントを切り替えるコード:
var compName = ko.observable();
//...
compName(switchToComponent);
setTimeout(function(){
// this code is queued until after the component is rendered.
}, 0);