Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Vue bind after AJAX partial loads?

I am just getting started with Vue.js and trying to incorporate it into an app I've been building for a while. My app is built using Laravel, a fair amount of jQuery, etc.

All of my navigation elements in my app are using AJAX (not via Vue) to return partial views. So any internal link or form submission is submitted via AJAX to a Laravel route that returns a partial.

I have set up my first Vue instance but it only binds to the element the first time the visitor hits the page where the Vue instance is used. The Vue instance still exists but it looses it's binding to the element when the user navigates away from the page and then comes back -- presumably because the element has been removed from the DOM when the user navigated away.

How do I get Vue to bind back to the element when it returns to the DOM (via an AJAX load that isn't performed by Vue)?

My main.js (consumed by Elixir / Browserify):

window.MaintenanceStatus = require('./components/Status.js');

Status.js

var Vue = require('vue');
Vue.use(require('vue-resource'));

module.exports = new Vue({
    el: '#app',

    data: {
        message: ''
    },

    ready: function() {
        this.message = 'loading ...';
    },

    methods: {
        setMessage: function(message) {
            this.message = message;
        },

        getStatus: function(url, data) {
            this.message = 'loading ...';
            this.$http.get(url, data)
                .success(function(result) {
                    console.log('Status get success');
                    this.setMessage(result);
                })
                .error(function() {
                    console.log('Status get error');
                    this.setMessage('Error');
                });
        }
    }
});

The consuming code which is a partial/template that is returned via AJAX ...

@extends('layouts.partials.content')


@section('content')
    <div id="app">
        <pre>@{{ $data | json }}</pre>
    </div>
@stop

@section('javascript')
<script type="text/javascript" class="document-script">
$(function()
{
    var href ...
    var data {...}

    MaintenanceStatus.getStatus(href, data);
});
</script>
@stop

Note that it works on a full page refresh but if I navigate to another page (again that's an AJAX call) then I return back to this view, I just see {{ $data | json }} ... Vue seems to have lost it's binding to the app element. How do I get it back?

I tried binding the Vue instance to an element that does not ever leave the DOM and then created a component but I get the same result ... the component renders on a full page refresh but not when the partial is loaded via AJAX.

I also tried messing around with .$mount, but that had no effect.

like image 422
Christopher Raymond Avatar asked Nov 24 '15 18:11

Christopher Raymond


1 Answers

I recommend you taking a look at the activate hook here.

From the Doc:

component = {
  activate: function (done) {
    var self = this
    loadDataAsync(function (data) {
      self.someData = data
      done()
    })
}

Basically call done() when the data is ready. The component will be then inserted

like image 156
Posva Avatar answered Oct 17 '22 10:10

Posva