0

I want set page titles which change according to route. I mean Responsive titles.

I have a directive in my module:

mainModule.directive("pageTitle", function($state){
return {
    restrict: 'A',
    template: "{{title}}",
    scope: {title: '=title'},
    link: function (scope, elem, attr) {
        scope.title=$state.current.data.title; //wrap this in $watch
        console.log('page state',$state.current.data.title);
    }
  } 
})

in my main.cshtml I have this title directive in head tags:

<title><page-title title="{{$state.current.data.title}}"></page-title></title>

And I have stateProvider in my config file:

$stateProvider
        .state('a-management', {
            name: 'aManState',
            url: '/a-management',
            template: '<div license-a permissions = permissions></div>',
            data: {title: 'A Management'}
        })
        .state('b-management/bs', {
            url: '/b-management/bs',
            template: '<b-management current-user = currentUser permissions = permissions></b-management>',
            data: {title: 'B Management'}
        })

And I used ui-sref-active="active" too. Everything looks fine, but when I run website this doesn't work. I open the console and look what I have, looks like it can reach $state (by state service) but the its current property is empty.

Why can't my code reach current, so current.data too? Is there anything I missed?

codergirrl
  • 145
  • 1
  • 11

3 Answers3

0

I am just going throw another solution where you wouldn't need to use a directive (may or may not be interested, but this is what I do). I essentially have a run command, that listens for state changes, and then update the page title through the root scope based on a title variable passed into the state. From there, the page title (index.html) is bound to the title in the root scope.

app.js

// Insert code here 
app.run(function ($rootScope) {
    $rootScope.$on('$stateChangeSuccess', function (event, toState) {
        $rootScope.title = toState.title || 'Default Title';
});


// Insert code here
.state('', {
    url: '/',
    title: 'Random Title'
}

index.html

    <head>
    <title ng-bind="title">Default Title</title>
    </head>

Hopefully this makes sense and helps you out?

CoolestNerdIII
  • 770
  • 4
  • 10
  • thank you but it's still not working, no error given, still can't get titles so weird T_T – codergirrl Sep 28 '18 at 13:42
  • What part isn't getting the title? I guess I should also ask which version of ui-router are you using? – CoolestNerdIII Sep 28 '18 at 14:01
  • There is no title in any page. "angular-ui-router": "^1.0.20" – codergirrl Sep 28 '18 at 14:07
  • So, just for debugging, you may want to log and make sure that the stateChange is being caught when you change pages. You also will need to make sure that you bind the title properly. So, assuming you have some type of parent controller over the entire app, you will need to set the title variable in there – CoolestNerdIII Sep 28 '18 at 14:19
  • stateChange is not being caught because I put console.log and there's no output – codergirrl Sep 28 '18 at 14:23
  • Sorry I overlooked that you are using the newest version of ui-router. You would have to use transition hooks as described by @Fabio in his answer instead of listening for state changes. I can update my answer if you want? – CoolestNerdIII Sep 28 '18 at 14:40
  • Okay I will go on from that way. Thank you so much for attention – codergirrl Sep 28 '18 at 15:04
0

With newest version of UI-Router you can use Transition Hooks (docs here) to achieve that result:

You can write your page-title.directive.js as:

mainModule.directive("pageTitle", function(){
return {
    restrict: 'A',
    template: "{{title}}",
    scope: {},
    controller: function ($scope, $transitions) {
        $transitions.onSuccess({}, function (transition) {
            //
            $scope.title = transition.to().title; // Your current state's title
        });
    }
  } 
})

And your state definition will be:

$stateProvider.state('myState', {
    url: '/',
    title: 'My State Title',
    ...
})

Always try to avoid accessing (or emitting on) $rootScope if it isn't your last chance to achieve your result.

Hope it helps.

Fabio Ruggiero
  • 309
  • 2
  • 7
  • this code is super good but it doesn't work too. no error again no title... – codergirrl Sep 28 '18 at 13:53
  • Make sure you are declaring your directive. No error let me thinks firstly on this kind of oversight. – Fabio Ruggiero Sep 28 '18 at 14:02
  • you are so right directive doesnt work. I did like is that it true : {{title}} – codergirrl Sep 28 '18 at 14:17
  • You should use it as:
    . Remember to convert to a "dashed" name your directive name when used inside a template.
    – Fabio Ruggiero Sep 28 '18 at 14:20
  • still doesn't work. I guess in this part transition.to().title couldnt find title. but I don't know why. – codergirrl Sep 28 '18 at 14:34
  • This should help you with your problem, but for what are you saying i think that maybe there is no active state to display. Make sure you are activating a state with a title prop in his definition – Fabio Ruggiero Sep 28 '18 at 14:45
  • I want to ask a question about active. I used active like this ui-sref-active="active" Is this true? Should I specify about title this line or I don't please help me – codergirrl Oct 01 '18 at 06:17
  • Yes, the usage will be similar, but you have to handle this "template injection" manually. ui-sref-active only cares about adding css classes but the behaviour is the same of your particular case – Fabio Ruggiero Oct 01 '18 at 10:38
0

Thanks for helping guys, In this question cwbutler's answer solved this.

[Set Page title using UI-Router

codergirrl
  • 145
  • 1
  • 11