Does afterRender work with Knockout components?

匿名 (未验证) 提交于 2019-12-03 01:18:02

问题:

afterRender works with template bindings, but after converting my templates to components, there does not seem to be any way to use afterRender. I have tried looking for an example of a component that uses afterRender, but cannot find anything.

回答1:

I could not get the method working as per the above post. However i found a workaround on the git issue list and it doesn't require a custom KO Binding.

Add the below line in your component template html or string of code.

  

Then create a init function in your module / viewModel:

 this.init = function() {    Do cool DOM stuff here. } 

or depending on your viewModel structure:

viewModel: function(params) {     return {         init: function () {          }     }; }, 

Works like a charm. Example of it working is here

http://jsfiddle.net/gLcfxkv6/1/

Thread on knockout git here: https://github.com/knockout/knockout/issues/1533

Thanks to vamps on git for the workaround.



回答2:

The secret here is 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);   } }; 

so in my component template I do something like

and on the component viewModel I just implement init and/or update, for example:

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(); }; 

The Knockout documentation could be improved by pointing out this very useful case. Also, this is such a useful binding, there should be a standard bindings for 'init' and 'update', for example



回答3:

We needed to access DOM elements in a component after switching between different components. We would have liked to use the non-existing "afterRender" binding on components.

We solved it with a Javascript setTimeout, letting KO do its rendering first, and in effect queueing our code after that.

HTML:

The code switching the component:

var compName = ko.observable();  //...  compName(switchToComponent); setTimeout(function(){     // this code is queued until after the component is rendered. }, 0); 


标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!