Reputation: 1019
I'm struggling with binding in Component Router.
It is said in the Developer's Guide you should avoid using $scope in components therefore objects have to be passed through binding.
Based on examples in: https://docs.angularjs.org/guide/component and https://docs.angularjs.org/guide/component-router I came up with:
HTML:
<div ng-app="app" ng-controller="MainCtrl as ctrl">
{{ ctrl.hero.name }}
<app></app>
</div>
Javascript:
'use strict';
var app = angular.module('app', [
'ngComponentRouter',
'testComponent',
])
.config(function($locationProvider) {
$locationProvider.html5Mode(true);
})
.value('$routerRootComponent', 'app')
.controller('MainCtrl', function(){
this.hero = {
name: 'Spawn'
};
})
.component('app', {
template: '<ng-outlet></ng-outlet>',
$routeConfig: [
{path: '/test', name: 'Test', component: 'testComponent'},
],
})
var testComponent = angular.module('testComponent', []);
testComponent.component('testComponent', {
template: '<span>Name: {{$ctrl.hero.name}}</span>',
controller: TestComponentController,
bindings: {
hero: '=',
}
});
function TestComponentController() {
}
But <span>Name: {{$ctrl.hero.name}}</span>
doesn't show "Spawn" or anything.
Upvotes: 0
Views: 2567
Reputation: 1225
You cannot use the "bindings" definition in router components as the component doesn't have any HTML use that you would control.
If you need to pass in data to the routing component you would access routing parameters in the $routerOnActivate callback.
https://docs.angularjs.org/guide/component-router
Sample code to get started here: https://github.com/brandonroberts/angularjs-component-router/
Upvotes: 2
Reputation: 611
I don't think there is a good solution for that yet in the ngComponentRouter for angular 1.x. Since it's still under active development, I am hopeful that a better solution will arise in the next iterations.
In the meantime, what I do is that I make the component depends on its parent via require.
EDIT: I understand now that you want to keep MainCtrl as the top controller, so I have edited the code:
.component('app', {
template: '<ng-outlet></ng-outlet>',
bindings: {
hero: '<' // we have to bind here since you want to pass it from MainCtrl
},
$routeConfig: [
{path: '/test', name: 'Test', component: 'testComponent'}
],
})
var testComponent = angular.module('testComponent', []);
testComponent.component('testComponent', {
template: '<span>Name: {{$ctrl.hero.name}}</span>',
controller: TestComponentController,
require: {
appCtrl: '^app',
}
});
function TestComponentController() {
var ctrl = this;
ctrl.$onInit = function(){
ctrl.hero = ctrl.appCtrl.hero
}
}
And then html should then be:
<div ng-app="app" ng-controller="MainCtrl as ctrl">
<app hero="ctrl.hero"></app>
</div>
See working codepen: http://codepen.io/bchazalet/pen/qZYzXM?editors=1111
It's not ideal, because it introduces a dependency (in your case from testComponent to app) but it works.
Upvotes: 1
Reputation: 824
If you still need this, i this the bindings works with html attr so you html should be
enter <div ng-app="app" ng-controller="MainCtrl as ctrl">
{{ ctrl.hero.name }}
<app hero="ctrl.hero.name"></app>
</div>
and your binding i think should be
bindings: {
hero: '<'
}
Upvotes: -1