Reputation: 1114
I have this Vue instance:
var vm = new Vue({
el: '#app',
data: {
user: {
email: '',
password: '',
passwordconfirm: '',
bars: {},
authentication_token: '',
id: 0
}
},
components: {
dashboard: dashboard
},
events: {
'onLoginSuccesfull': function(user) {
// do stuff with user obj
this.$broadcast('onUserLoggedIn');
}
}
}
It has a 'dashboard' component:
var dashboard = Vue.extend({
template: '#dashboard',
data: function() {
return {
currentPage: 'main'
}
},
components: {
'dashboard-mainpage': dashboardmainpage
}
events: {
'onUserLoggedIn': function() {
alert('I should be firing bu I am not!');
}
}
});
Vue.component('dashboard', dashboard);
The 'dashboard' has a 'dashboard-mainpage' component:
var dashboardmainpage = Vue.extend({
template: '#dashboard-mainpage',
methods: {
loadData: function() {
this.$http.get('/dashboard/main.json', {
authenticity_token: window._token
}).then(function(response) {
var data = JSON.parse(response.body);
console.log(data);
}, function(response) {
console.log(response);
this.$dispatch("onRequestUnauthorized");
});
}
},
events: {
'onUserLoggedIn': function() {
alert('I should be firing as well but I am not!');
this.loadData();
}
}
});
The problem is that when the 'onLoginSuccesfull' event is triggered on the main Vue instance, the subsequently broadcasted 'onUserLoggedIn' on the 1st and 2nd level descendant are not triggered, when calling 'this.$broadcast('onUserLoggedIn');'.
I know that event callbacks must return true to keep propagating down the chain but the first event callback (on 'dashboard') is not even triggered.
What am I missing?
Thanks!
===== EDIT =====
Main app:
<div id="app">
<dashboard v-if="currentStep == 'dashboard'" v-bind:appname="appName" v-bind:dashboard-vm="dashboard" v-bind:user="user" v-bind:bar.sync="bar"></dashboard>
</div>
Dashboard template:
<template id="dashboard">
<div class="container body">
<div class="main_container">
<div class="col-md-3 left_col">
<div class="left_col scroll-view">
<div class="navbar nav_title" style="border: 0;">
<a href="index.html" class="site_title"><span>The Bar</span></a>
</div>
<div class="clearfix"></div>
<br />
<!-- sidebar menu -->
<div id="sidebar-menu" class="main_menu_side hidden-print main_menu">
{{ user.email }}
<div class="menu_section">
<ul class="nav side-menu">
<li><a v-on:click="createNewBar"><i class="fa fa-plus"></i> Create new bar</a>
</li>
<li><a v-on:click="showDashboard"><i class="fa fa-bar-chart"></i> Dashboard</a>
</li>
<li><a v-on:click="showBars"><i class="fa fa-bars"></i> Bars</a>
</li>
<li><a><i class="fa fa-tachometer"></i> Settings <span class="fa fa-chevron-down"></span></a>
<ul class="nav child_menu">
<li><a v-on:click="showProfile">Profile</a></li>
<li><a v-on:click="showPaymentsPlans">Plan & payments</a></li>
</ul>
</li>
</ul>
</div>
</div>
<!-- /sidebar menu -->
</div>
</div>
<!-- top navigation -->
<div class="top_nav">
<div class="nav_menu">
<nav>
<div class="nav toggle">
<a id="menu_toggle"><i class="fa fa-bars"></i></a>
</div>
<ul class="nav navbar-nav navbar-right">
<li class="">
<a v-on:click="$parent.logoutUser" style="cursor: pointer">Log out</a>
</li>
</ul>
</nav>
</div>
</div>
<!-- /top navigation -->
<!-- page content -->
<div class="right_col" role="main">
<dashboard-mainpage v-if='currentPage == "main"' v-bind:vm="dashboardVm"></dashboard-mainpage>
</div>
</div>
<!-- /page content -->
<!-- footer content -->
<footer>
<div class="pull-right">
© <%= Time.now.year %> The Bar
</div>
<div class="clearfix"></div>
</footer>
<!-- /footer content -->
</div>
</div>
</template>
Dashboard-mainpage:
<template id="dashboard-mainpage">
<div class="col-md-12 x_title">
<div>
<div class="btn-group pull-right">
<button type="button" class="btn btn-info"><span class="fa fa-calendar" aria-hidden="true"></span> Today</button>
<button type="button" class="btn btn-info dropdown-toggle" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
<span class="caret"></span>
<span class="sr-only">Toggle Dropdown</span>
</button>
<ul class="dropdown-menu">
<li>
<a href="#">Today</a>
</li>
<li>
<a href="#">Yesterday</a>
</li>
<li>
<a href="#">Last 7 days</a>
</li>
<li>
<a href="#">Last 30 days</a>
</li>
<li>
<a href="#">Last year</a>
</li>
<li>
<a href="#">All</a>
</li>
</ul>
</div>
<span class="pull-right">Filter:</span>
</div>
</div>
<!-- top tiles -->
<div class="row top_tiles">
<div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
<div class="tile-stats">
<div class="icon"><i class="fa fa-bars"></i></div>
<div class="count">{{ vm.totalBars }}</div>
<h3>Total bars</h3>
<p>All you active bars</p>
</div>
</div>
<div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
<div class="tile-stats">
<div class="icon"><i class="fa fa-eye"></i></div>
<div class="count">{{ vm.totalViews }}</div>
<h3>Total views</h3>
<p>Total number of bar views</p>
</div>
</div>
<div class="animated flipInY col-lg-4 col-md-4 col-sm-6 col-xs-12">
<div class="tile-stats">
<div class="icon"><i class="fa fa-mouse-pointer"></i></div>
<div class="count">{{ vm.totalClicks }}</div>
<h3>Total clicks</h3>
<p>Total number of clicks</p>
</div>
</div>
</div>
<!-- /top tiles -->
<div class="row">
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="dashboard_graph">
<div class="row x_title">
<div class="col-md-6">
<h3>Statistics</h3>
</div>
<div class="col-md-6">
<div id="reportrange" class="pull-right" style="background: #fff; cursor: pointer; padding: 5px 10px; border: 1px solid #ccc">
<i class="glyphicon glyphicon-calendar fa fa-calendar"></i>
<span>December 30, 2014 - January 28, 2015</span> <b class="caret"></b>
</div>
</div>
</div>
<div class="col-md-12 col-sm-12 col-xs-12">
<div class="x_title">
<h2>Sub title</h2>
<div class="clearfix"></div>
</div>
<p>stats here</p>
</div>
<div class="clearfix"></div>
</div>
</div>
</div>
<br />
</template>
Upvotes: 3
Views: 2117
Reputation: 1114
Ok. For anyone who is going to wander onto this "issue". Here's the fix.
I used 'v-if' attributes on the children that were listening to the 'onUserLoggedIn' event. The docs for 'v-if' say:
Conditionally render the element based on the truthy-ness of the expression value. The element and its contained data bindings / components are destroyed and re-constructed during toggles. If the element is a element, its content will be extracted as the conditional block.
So, when 'v-if = "something false"' on some child component it practically does not exist and thus is not able to do or respond to anything, including events.
When using 'v-show' instead of 'v-if' to conditionally toggle certain components, the component stays "alive" and will be able to respond.
Upvotes: 1
Reputation:
Some stuff going on:
app
component, there is no need to define this component globally (https://vuejs.org/guide/components.html#Registration-Sugar).App
component, so I assume there is none.onLoginSuccesfull
never gets actually called on the App
component to begin with!true
.Here's a working jsfiddle with the basics covered: https://jsfiddle.net/e85ekxk1/2/
Good luck!
Upvotes: 0