I have a Rails 5 app using webpacker that displays a list of users. The logic to do so is in a partial that has Vue component code in it, like
<profile_modal>
<template slot="trigger">
<figure class="profile-card__figure | image -is1x1">
<img src="<%= person.avatar.url %>" alt="">
</figure>
...
Everything works well, and the .erb changes this correctly to HTML when the page is processed. So far so good.
Now I've added a button that says "show more users" that makes an ajax call to pull in more users. I've made a js.erb that has in it:
$("#users").html("<%= escape_javascript(render partial: 'layouts/components/profile-card--modal', collection: @users.last(12), as: :person, locals: { content: @users_presenter.profile_modal }) %>");
This code is executed, but instead of converting the "profile_modal" to the right html, rails is just inserting it right in the page, which makes everything wrong.
Is there a way I can have the vue code be transpiled into the html it would become during normal, non-ajaxy processing?
The best way to force Vue to re-render a component is to set a :key on the component. When you need the component to be re-rendered, you just change the value of the key and Vue will re-render the component.
js developers "what's the best way to use AJAX in an app?" you'll get three different opinions. Vue doesn't provide an official way of implementing AJAX, and there are a number of different design patterns that may be used effectively.
Using Props To Share Data From Parent To Child. VueJS props are the simplest way to share data between components. Props are custom attributes that we can give to a component. Then, in our template, we can give those attributes values and — BAM — we're passing data from a parent to a child component!
Usually, Vue will react to changes in dependencies by updating the view. However, when we call $forceUpdate method, we can force that update to occur, even if none of the dependencies has actually changed.
You shouldn't call a render for a whole component, you should instead make a global component that receives an array of users as variable, something in the lines of:
window.users = [
{ id: 'this-is-an-id', name: 'Evan', age: 34 },
{ id: 'unique-id', name: 'Sarah', age: 98 },
{ id: 'another-unique-id', name: 'James', age: 45 },
];
<ul>
<li v-for="person in users" :key="person.id">
{{ person.name }} - {{ person.id }}
</li>
</ul>
Then when you change the users
variable, your Vue component will change too. So instead of overriding the whole HTML for the component, make you .js.erb
append to users variable:
response_users = <%=j @users.last(12).as_json %>;
Object.assign(users, response_users);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With