Skip to content

is there a more idiomatic way to dynamically change components #163

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
jcaxmacher opened this issue Mar 7, 2014 · 10 comments
Closed

is there a more idiomatic way to dynamically change components #163

jcaxmacher opened this issue Mar 7, 2014 · 10 comments

Comments

@jcaxmacher
Copy link

Here's a stripped down version of what I want to do. My question is if there is a better / more idiomatic way to do this (with or without the new conditional components capability). A couple things I think are wrong / less than ideal with the current example:

  • Creating new ViewModels in a directive
  • Naive $appendTo in the directive without regard to existing markup
  • The data element of the model that is being sent to the dynamic components is hard coded and cannot be passed in

The components that are being swapped in and out are simplistic to keep the example simple (I know there are easier ways to switch a class :) )

I think something like this would be pretty cool, but it does not work.

@thelinuxlich
Copy link

+1

@yyx990803
Copy link
Member

It's fine to create childVMs in directives as long as you manage them well - that's how some internal directives are implemented too.

There's an internal method on Compiler instances called getOption, which allows you to get a constructor that's available to the current instance. Here's an example of using that approach: http://jsfiddle.net/yyx990803/LgzwF/

To address your $appendTo concern - what you can do is on bind, remove and cache the current innerHTML as a DocumentFragment. When instantiating new childVM's, in their created hook set its compler's rawContent with a clone of the cached fragment. That way you can leverage the {{>yield}} outlet as normal components do. Note this requires you to use the dynamic component directive like v-component - basically if you don't provide {{>yield}} your inner content will be wiped away.

@thelinuxlich
Copy link

a bit cumbersome

@yyx990803
Copy link
Member

Because dynamically swapping components is not that easy :)
That said, it is still possible to create a pretty robust directive that does exactly what you want.

@jcaxmacher
Copy link
Author

Thanks, @yyx990803. That all makes a lot of sense and will let me fix some of the rough edges of the dynamic component. Any ideas why the second example I gave does not work? Something to do with the compilation order? It seems to get stuck in a loop.

@yyx990803
Copy link
Member

I've got a pretty rough implementation here: http://jsfiddle.net/yyx990803/LgzwF/3/

It accounts for:

  • {{>yield}}
  • v-with
  • actually swaps the outside node!

@jcaxmacher
Copy link
Author

Very cool. Is this something that belongs in userland? How would you compare the complexity of this directive to others directives you've built for real projects which did not make it into "core" Vue?

@yyx990803
Copy link
Member

I'd say it should be pretty rare to do this type of logic control directives in userland...
I'll think about enabling the kind of dynamic interpolation in your second example, but I can see that taking some time.

@yyx990803
Copy link
Member

Introduced new directive: v-view in 10a0cc1 . It's based on the previous dynamic component test implementation. I find it more suitable for view control, but you can use it as a dynamic component directive too. Checkout the updated routing example.

@thelinuxlich
Copy link

wow this is so cool!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants