afterRender
与模板绑定一起工作,但是在将我的模板转换为组件后,似乎没有任何方法可以使用afterRender
. 我曾尝试寻找使用 的组件的示例afterRender
,但找不到任何东西。
5 回答
我无法使该方法按照上述帖子工作。但是我在 git issue list 上找到了一种解决方法,它不需要自定义 KO 绑定。
在组件模板 html 或代码字符串中添加以下行。
<span data-bind="template: { afterRender: init }"></span>
然后在你的模块/视图模型中创建一个初始化函数:
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/1533
感谢 git 上的 vamps 解决方法。
这里的秘密是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 上,我只实现了初始化和/或更新,例如:
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);
从淘汰赛 3.5.1 开始,您可以koDescendantsComplete
向您添加一个函数,该函数viewModel
将在渲染完成后触发
var viewModel = {
koDescendantsComplete: element => {
console.log( 'Rendered!', element );
}
}
做一个新的绑定,像这样
ko.bindingHandlers.initBinding = {
init: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
debugger
if (valueAccessor() && valueAccessor().afterRender && bindingContext.$data) {
valueAccessor().afterRender(bindingContext.$data);
}
},
update: function (element, valueAccessor, allBindings, viewModel, bindingContext) {
}
};
export default ko.bindingHandlers.initBinding
如果您不使用 ES6(babel 等),则不需要导出。
然后在你的组件 html 中,你可以做这样的事情
<div class="staff-directory" data-bind="initBinding: {afterRender: afterRender }">
<p>Loaded</p>
</div>
在你的组件模型中
class staffDirectory {
constructor() {
console.log('staff directory loaded');
}
afterRender() {
console.log('afterRender called');
}
}
export default staffDirectory;