Jeffrey Roosendaal Jeffrey Roosendaal - 2 months ago 18
Javascript Question

How to properly use the same AngularJS 1.5 component multiple times in a view?

I'm creating a set of widgets with AngularJS 1.5's new components. The problem is, when using the same widget multiple times, they somehow share their controller or scope. I thought one of the things about components was that their scope is completely isolated?

My main html template which hold the widgets:

class="col-xs-12 col-md-4">

class="col-xs-12 col-md-4">

class="col-xs-12 col-md-4">

My widget template:

<div class="widget widget-list">
<div class="panel b-a">

<div class="panel-heading b-b b-light">
<div class="pull-right">
<button type="button" class="btn btn-default btn-sm" ng-click="$widget.doSomething()">
Do something

<div class="panel-content">
{{$widget.content || 'No content'}}


My widget component:

app.component('widgetList', {
templateUrl: 'template/widget/widget-list.html',
bindings: {
title : '@',
controllerAs: '$widget',
controller: function($timeout) {

$widget = this;

console.log('Title on init: ', $widget.title)

$timeout(function() {
console.log('Title after 3 seconds: ', $widget.title)
}, 3000)

$widget.doSomething = function() {
$widget.content = "Something";

When running my code, this is what my console looks like:

Title on init: Books
Title on init: Movies
Title on init: Albums
(3) Title after 3 seconds: Albums

Also after rendering, all three widgets display
No content
in their template. But, when clicking the
button in either one of the three widgets, only the content of the last widget updates to

What is happening here? Why are my components not 'isolated'?


Looks like you have a global variable called $widget here, try this:

var $widget = this;

instead of

$widget = this;

It creates a mess since the $widget variable holds a reference to the controller that has been recently initialized, in this case to the controller of the third component.