I am wondering on how to get the inserted event so that I can manipulate the element with jQuery once the component is loaded.
Thanks!
I am wondering on how to get the inserted event so that I can manipulate the element with jQuery once the component is loaded.
Thanks!
Nevermind, that has not changed from 2.*
var AuthLogin = Component({
tag: 'page-auth-login',
view: loginTemplate,
ViewModel: AuthLoginViewModel,
events: {
inserted: function(){
console.log( 3333 );
}
}
});
Sorry for the post I don’t think I can delete it.
The only difference is that the inserted
and removed
events are now asynchronous in Can 3.x. Check out the section Asynchronous inserted/removed events on the migration guide.
Thanks for the heads up!
I have an {{#if init_loaded}} wrapped around the whole template, that is default to false. In the init event I am using a model to get some data, and then once the data is loaded I set the init_loaded variable to true,
I have to call taskGroupTemplate(); before jQuery can find an element, inside the {{#if init_loaded}}. Otherwise the element that jQuery is looking for never exists because the template is not processed and re-rendered yet.
Is this proper?
taskGroupTemplate is the view, imported via StealJs. It is used as the main view for the Component.
inserted: function( element ){
this.viewModel.on('init_loaded', function(ev, newVal, oldVal) {
if( newVal ) {
taskGroupTemplate();
console.log( $( this.element ).find( '.someitem' ) );
}
}.bind( this ));
}
Thanks!
The code above is what you’re using to work around the issue, is that correct?
It would be helpful to see what the code looked like when it was not working. If you could create a JSBin that would be the easiest way to debug, but posting the non-working code here would work also.
Yeah, it is what I am using to get around the issue.
Here is the JSbin:
You can see that the console.log( this.element.querySelector( ‘#test’ ) ); returns null if the MyComponentTemplate(); function is not called.
setTimeout is to simulate an ajax call.
var MyMap = can.DefineMap.extend('MyMap', {
init_loaded: {
value: false
},
});
var MyComponentTemplate = can.stache( '{{#if init_loaded}}<div id="test">test element</div>{{/if}}' );
var MyComponent = can.Component.extend({
tag: 'my-component',
viewModel: MyMap,
view: MyComponentTemplate,
events: {
init: function(){
//this.viewModel.init_loaded = true;
setTimeout(function(){
this.viewModel.init_loaded = true;
}.bind( this ), 2000);
},
inserted: function( element ){
if( this.viewModel.init_loaded ) {
//console.log( this.element.getElementById( 'test' ).style.color = "red" );
//console.log( this.element.querySelector( '#test' ) );
}
this.viewModel.on( 'init_loaded', function( ev, newVal, oldVal ){
if( newVal ) {
//MyComponentTemplate();
console.log( this.element.querySelector( '#test' ) );
}
}.bind( this ));
}
}
});
var MyRender = can.stache( '<my-component/>' );
var fragment = MyRender( )
document.body.appendChild(fragment)
I must be missing something.
Thanks!
Ok, I see what you’re saying now. When init_loaded
changes, this handler
this.viewModel.on( 'init_loaded', function( ev, newVal, oldVal ){ ... });
is triggered before stache rerenders and adds your #test
element to the DOM. Calling MyComponentTemplate();
just adds a delay so that the DOM can be updated before running your code.
There are a couple options I can think of for fixing this.
setTimeout
around your code within the handler this.viewModel.on( 'init_loaded', function( ev, newVal, oldVal ){
if( newVal ) {
setTimeout(function() {
console.log( this.element.querySelector( '#test' ) );
}.bind(this));
}
}.bind( this ));
This will allow the template to be rendered before that querySelector
runs, but makes the code more confusing and less testable.
($inserted)
handler to the #test
element directly, so your template will look something like:{{#if init_loaded}}
<div id="test" ($inserted)="testInserted(%element)">test element</div>
{{/if}}
<div id="test">
element its own component so you can handle the code in the inserted
handler of that component.Thanks, I’ll probably go with #2 since it is the easiest to implement.
I just tried it, and it works perfectly!