Bump.
Vue.js component not compiling when being loaded in via AJAX pagination
I have a comments section which works similar to Facebook in that it will load the first 5 and then if there are more than 5 it will display a "Load more comments" link.
Upon clicking the link it will load the next 5 comments via a $.get() call.
The first 5 load and compile just fine since they're not being loaded via AJAX. The problem I'm having is that the Vue code isn't being compiled when the components are loaded via AJAX. So <div v-if='editing'> will stay as it is in the HTML rather than be executed.
How would I be able to get these Vue components to compile when they're loaded in? I don't want to have to load every single comment upon page load since there could be 100+ comments.
My controller function which loads the comments:
public function loadMoreWallPostComments(Request $request, WallPost $wallPost)
{
$commentsLoaded = $request->input('commentsLoaded');
$load = "";
foreach ($wallPost->wallPostComments()->with('likes', 'likesLinked')->limit(5)->offset($commentsLoaded)->get()->reverse() as $comment)
{
$load .= $comment->display();
}
return $load;
}
Each comment is a Vue component. The display() function:
public function display()
{
$display = "<li><wallpostcomment :model='".htmlentities($this)."' inline-template><div class='wall-post-comment'>
<div class='wall-post-comment-avatar'>".$this->user->imageLink('img-fluid rounded-circle')."</div>
<div class='wall-post-comment-body'>
<div class='wall-post-comment-body-content'>
<div v-if='editing'>
<textarea class='wall-post-comment-edit form-control' name='body' v-model='editParsed'></textarea>
<button class='btn btn-sm btn-primary' @click='update'>Update</button><button class='btn btn-sm btn-secondary ml-1' @click='cancel'>Cancel</button>
</div>
<div v-else>
<span class='wall-post-comment-author'>".$this->user->nameLink()."</span> <span v-html='bodyParsed'></span>
<div class='wall-post-comment-info'>
<span>".$this->created_at->diffForHumans()."</span><a @click='editing = true'>Edit</a><a @click='deleting = true'>Delete</a>
</div>
</div>
</div>
</div>
</div></wallpostcomment></li>";
return $display;
}
WallPostComment.vue:
<script>
import Like from './Like.vue';
export default {
props: ['model'],
components: (Like),
data() {
return {
editing: false,
deleting: false,
deleted: this.model.isDeleted,
bodyParsed: this.model.bodyParsed,
editParsed: this.model.editParsed,
previousEditParsed: this.model.editParsed
}
},
mounted() {
$('#body').atwho({
at: "@",
delay: 750,
callbacks: {
remoteFilter: function(query, callback) {
$.getJSON("/api/users/at", {name: query}, function(usernames) {
callback(usernames)
});
}
}
});
},
methods: {
update() {
axios.patch(this.model.url, {
body: this.editParsed
}).then((response) => {
this.bodyParsed = response.data;
this.previousEditParsed = this.editParsed;
this.editing = false;
flash('Wall post successfully updated.');
});
},
cancel() {
this.editParsed = this.previousEditParsed;
this.editing = false;
},
destroy() {
axios.delete(this.model.url).then((response) => {
$("#wall-post-"+this.model.id).remove();
flash('Wall post successfully deleted.');
});
}
}
}
</script>
Please or to participate in this conversation.