srokatonie
srokatonie

Reputation: 1019

Binding in Component Router - Angular 1.5

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

Answers (3)

Stefan Norberg
Stefan Norberg

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

Boris
Boris

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

Femi Oni
Femi Oni

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

Related Questions