Skip to content

attached #131

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
marfalkov opened this issue Feb 24, 2014 · 21 comments
Closed

attached #131

marfalkov opened this issue Feb 24, 2014 · 21 comments

Comments

@marfalkov
Copy link

Foo getting rendered in both cases but the attached callback never get called in the first case.
jsfiddle: http://jsfiddle.net/marfalkov/B8vZL/

var Foo = Vue.extend({
    template: "<p>foo</p>",
    attached: function() {
        console.log("I'm attached"); // only run in test2
    }
})

var test1= new Vue({
    template: "<div v-component='foo'></div>",
    components: {
        foo: Foo
    }
})
test1.$appendTo("body")

var test2 = new Foo()
test2.$appendTo("body")
@marfalkov
Copy link
Author

I can do something like the above but it feels complicated.

var Foo = Vue.extend({
    template: "<p>foo</p>",
    ready: function() {
        var self = this;
        this.$on("attached", function() {
            self.onAttached();
        });
    },
    methods:{
        onAttached: function() {
            console.log("I know I'm attached");
        }
    },
    attached: function() {
        console.log("I'm attached"); // only run in test2
    }
})

var test1= new Vue({
    template: "<div v-component='foo'></div>",
    components: {
        foo: Foo
    },
    attached: function() {
        this.$broadcast('attached');
    }
})
test1.$appendTo("body");

var test2 = new Foo();
test2.$appendTo("body");

@duckbox
Copy link

duckbox commented Feb 24, 2014

From what I can see in the fiddle, attached gets called. The console logs out I'm attached ?

@duckbox
Copy link

duckbox commented Feb 24, 2014

fiddle : http://jsfiddle.net/duckbox/X7Bek/

@marfalkov
Copy link
Author

As you can see it only gets called in the second case.

@duckbox
Copy link

duckbox commented Feb 24, 2014

Ahhhhhh. ffs.

@marfalkov I do apologize, I get what you are saying now. No, on explicitly setting a child component, the attach event does not fire. If this is an error by design, I'm not sure.

But if you use the 'created' method, instead of attached, you get the outcome you are looking for.

@marfalkov
Copy link
Author

@duckbox No problem :) Unfortunately I have to use the attached callback because I have a big mixed jquery-knockout datagrid and I can only build that up after vue attached the view.

@yyx990803
Copy link
Member

Just wondering why not just use test1's attached callback? If a parent is attached, so are all its children.

@marfalkov
Copy link
Author

@yyx990803 It would be more clean to keep the relevant code in the module's attached callback instead of the parent's attached callback, as I'm dynamically creating components based on events.

@marfalkov
Copy link
Author

Right now I have only one component that needs the attached callback, but imagine all the other components attached callbacks out here. It would be messy.

$self.$cnt = new Vue
  components:
    settings: Settings
    calendar: Calendar
    library: Library
    sampler: Sampler
    charts: Charts
    widgets: Widgets
    table: Table
  template: '<div v-component='+page.toLowerCase()+' v-ref="page-content"></div>'
  attached: ->
    if page is 'Table' then @$broadcast "table:attached"
$self.$cnt.$appendTo("#page-content")

@yyx990803
Copy link
Member

That's true. I think for now the solution is $broadcasting in the top level vm. I'll address this in next release.

@marfalkov
Copy link
Author

@yyx990803 That'll be awesome :)

@yyx990803
Copy link
Member

After some thought, it seems problematic to recursively fire attached/detached for all child components. These two events are meant to indicate the component element's relationship to its parentNode, not whether they are inside the DOM. This is consistent with the behavior of the native DOM mutation events.

As for your use case - can you do something like this?

new Vue({
    attached: function () {
        this.$broadcast(page + ':attached')
    }
})
// inside table component
created: function () {
    this.$on('Table:attached', ...)
}

@marfalkov
Copy link
Author

I can live with the $broadcast because it's only one case for now. But it would be good if we could have let's say an afterRendered callback.

@yyx990803
Copy link
Member

There's a ready hook which is fired after the compilation is done. Note a component can be compiled/rendered before being attached into the DOM.

@marfalkov
Copy link
Author

but it's fired before the view is rendered isn't?

@yyx990803
Copy link
Member

nope, when I'm saying "compilation" it's more or less the same thing as "rendering". When the ready hook is fired, it means all data bindings have been processed and the element has stabilized.

@marfalkov
Copy link
Author

that's strange because I tried the ready and it didn't work for this case. I'll look into that again, thanks!

@yyx990803
Copy link
Member

If you can provide a fiddle illustrating the problem you ran into with ready that would be great. Closing this for now.

@reemaalwail
Copy link

reemaalwail commented May 4, 2020

Now this is my problem 🤗
2020 🤭

@marfalkov
Copy link
Author

@reemaalwail now you can use a global event bus or vuex:

https://medium.com/@andrejsabrickis/https-medium-com-andrejsabrickis-create-simple-eventbus-to-communicate-between-vue-js-components-cdc11cd59860

@reemaalwail
Copy link

@vuejs vuejs locked as resolved and limited conversation to collaborators May 4, 2020
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants