如何基于AngularJS部分视图动态更改标头?


411

我正在使用ng-view来包含AngularJS部分视图,并且我想根据所包含的视图来更新页面标题和h1标头标签。但是,这些超出了部分视图控制器的范围,因此我无法弄清楚如何将它们绑定到控制器中的数据集。

如果是ASP.NET MVC,则可以使用@ViewBag来执行此操作,但我不知道AngularJS中的等效方法。我已经搜索了有关共享服务,事件等的信息,但仍然无法正常运行。任何修改我的示例使其可行的方法将不胜感激。

我的HTML:

<html data-ng-app="myModule">
<head>
<!-- include js files -->
<title><!-- should changed when ng-view changes --></title>
</head>
<body>
<h1><!-- should changed when ng-view changes --></h1>

<div data-ng-view></div>

</body>
</html>

我的JavaScript:

var myModule = angular.module('myModule', []);
myModule.config(['$routeProvider', function($routeProvider) {
    $routeProvider.
        when('/test1', {templateUrl: 'test1.html', controller: Test1Ctrl}).
        when('/test2', {templateUrl: 'test2.html', controller: Test2Ctrl}).
        otherwise({redirectTo: '/test1'});
}]);

function Test1Ctrl($scope, $http) { $scope.header = "Test 1"; 
                                  /* ^ how can I put this in title and h1 */ }
function Test2Ctrl($scope, $http) { $scope.header = "Test 2"; }

此评论可能已晚,但我想补充一下。cssfacts.com/simple-dynamic-meta-tags-in-angularjs这对于设置动态元数据很有用。您只需更改$ rootScope元变量。
KamuranSönecek'16

Answers:


342

您可以在<html>级别上定义控制器。

 <html ng-app="app" ng-controller="titleCtrl">
   <head>
     <title>{{ Page.title() }}</title>
 ...

您创建服务:Page并从控制器进行修改。

myModule.factory('Page', function() {
   var title = 'default';
   return {
     title: function() { return title; },
     setTitle: function(newTitle) { title = newTitle }
   };
});

Page从控制器注入并调用“ Page.setTitle()”。

这是具体示例:http : //plnkr.co/edit/0e7T6l


11
嗯...我不确定在AngularJS架构中是否将服务直接放入$ scope是不是很好。也许最好在$ scope中放入一个Controller函数,然后让该函数查询服务。
superjos 2013年

11
这个例子很棒。不过,我有一份后续报告,在初始加载时,您可以很快看到标题中的{{Page.title()}}文本。我不认为您可以使用ng-cloak,因为它不在体内。有什么建议可以避免这种情况?
亚瑟·弗兰克尔

52
@ArthurFrankel只需使用ng-bind(例如ng-bind =“ Page.title()”)
Pius Uzamere

2
或者我们可以在title标签中指定控制器,而无需在html标头上使用全局控制器:<title ng-controller =“ titleCtrl”> {{Page.title()}} </ title>
Dmitri

6
我个人更喜欢将标题设置为,$rootScope而不是创建其他控制器。
DDA 2014年

634

我刚刚发现了一种使用路由设置页面标题的好方法:

JavaScript:

var myApp = angular.module('myApp', ['ngResource'])

myApp.config(
    ['$routeProvider', function($routeProvider) {
        $routeProvider.when('/', {
            title: 'Home',
            templateUrl: '/Assets/Views/Home.html',
            controller: 'HomeController'
        });
        $routeProvider.when('/Product/:id', {
            title: 'Product',
            templateUrl: '/Assets/Views/Product.html',
            controller: 'ProductController'
        });
    }]);

myApp.run(['$rootScope', function($rootScope) {
    $rootScope.$on('$routeChangeSuccess', function (event, current, previous) {
        $rootScope.title = current.$$route.title;
    });
}]);

HTML:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title ng-bind="'myApp &mdash; ' + title">myApp</title>
...

编辑:使用ng-bind属性而不是curlies,{{}}这样它们就不会在加载时显示


11
是的,但是您的示例未显示如何更改由$ scope变量参数化的$ routeChangeSuccess的标题,@ tosh的使用Page服务的示例确实如此。因此您可以设置title = "Blog"但不能设置title = '{{"Blog post " + post.title}}'
埃里克·德雷赫瑟

10
@felix您可以访问标题一样current.title
Eldelshell

8
$ rootScope.title = current。$ route.title; 没有多
毛的

7
我刚刚将Angular版本升级了几个版本(从1.0.5到1.2.7),这在我的代码中使我很失望。我使用current.$route的是旧代码,因此可以正常工作。升级后,需要在路线上加倍$。current.$$route
泰勒·福赛斯

6
在回答的时候可以看到'/Product/:id'。有什么办法可以:id通过这种方法获得价值吗?我尝试过,title: function(params){return params.id;}但不起作用...可能正在使用resolve
mickaelb91 2014年

190

请注意,您还可以直接使用javascript设置标题,即

$window.document.title = someTitleYouCreated;

它没有数据绑定,但是在放入标签有问题时就足够ng-app<html>。(例如,使用<head>仅在一个位置定义的JSP模板,但您拥有多个应用程序。)


5
这是让它对我来说可以在Internet Explorer上运行的唯一方法,但是其他方法也可以在其他浏览器上使用
Maarten

4
正如Maarten所提到的,这是唯一在ie7和ie8中起作用的方法
rob

33
让人惊讶的是,人们如何不退缩,看到没有示波器和工厂就可以轻松完成这项工作
redben 2014年

7
难以置信的。这比其他人提到的所有恶作剧要简单得多。谢谢!
Leonard Teo

8
使用普通的“窗口”很好-直接作用于DOM。'$ window'是一个有角度的东西,您必须注入它才能使用它。无论哪种方式都可以。
broc.seib 2014年

119

ng-apphtml元素上声明可为head和提供根范围body

因此,在您的控制器中注入$rootScope并在其上设置标头属性:

function Test1Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 1"; }

function Test2Ctrl($rootScope, $scope, $http) { $rootScope.header = "Test 2"; }

并在您的页面中:

<title ng-bind="header"></title>

8
我认为最好的答案。在这种情况下,按照接受的答案所述在ng-app级别上具有控制器是没有用的。
Nicolas Janel 2014年

1
我喜欢这种解决方案的轻巧程度,并且避免使用$$属性
tedwards947

可接受的答案会增加不必要的复杂性和风险。此版本使它像设置变量一样简单。
2014年

3
如果您不愿意使用$ rootScope,那么我至少会将其提取到服务中,以便您的控制器中没有$ rootScope。
Michael J. Calkins 2014年

3
我想使用此解决方案,但我很好奇使用它的优势在哪里document.title = "App"
remarsh 2014年

43

angularjs-viewhead模块显示了一种仅使用定制指令就每个视图设置标题的机制。

它可以应用于内容已经是视图标题的现有视图元素:

<h2 view-title>About This Site</h2>

...或者它可以用作独立元素,在这种情况下,该元素将在呈现的文档中不可见,并且仅用于设置视图标题:

<view-title>About This Site</view-title>

该指令的内容在根作用域中以形式提供viewTitle,因此它可以像其他任何变量一样在title元素上使用:

<title ng-bind-template="{{viewTitle}} - My Site">My Site</title>

也可以在可以“看到”根范围的任何其他位置使用它。例如:

<h1>{{viewTitle}}</h1>

该解决方案允许通过用于控制演示文稿其余部分的相同机制来设置标题:AngularJS模板。这避免了使用此表示逻辑使控制器混乱的需求。控制器需要提供将用于通知标题的任何数据,但是模板将最终确定如何显示标题,并且可以正常使用表达式插值和过滤器绑定到范围数据。

(免责声明:我是该模块的作者,但在此引用它只是希望它可以帮助其他人解决此问题。)


4
不能相信这个解决方案还没有得到更多支持。其他大多数都是错误的设计选择。
Martin Wawrusch 2014年

同意,这应该是最佳解决方案。我比在页面级别上声明用于设置标题的控制器要好得多。仅供参考:与Angular v1.3.2和angular-route-segment v1.3.3一起使用时,它的工作原理很吸引人。
Nate Barbettini 2014年

我赞成这种解决方案;)
jkoreska,2015年

3
我写一点关于angularjs-viewhead这里另一个相关的想法在我的博客:apparently.me.uk/angularjs-view-specific-sidebars
马丁阿特金斯

如果在顶层和子层视图上重用同一视图,则仍可以将视图标题与ng-if一起使用,例如:<h4 ng-if =“ $ state.includes('some-state')” view-title> {{...}} </ h4>的详细信息<h4 ng-if =“!$ state.includes('some-state')”> {{...}} </ h4的详细信息>
anre 2016年

32

这是一种适用于我的调整后的解决方案,不需要将$ rootScope注入到用于设置资源特定页面标题的控制器中。

在主模板中:

<html data-ng-app="myApp">
    <head>
    <title data-ng-bind="page.title"></title>
    ...

在路由配置中:

$routeProvider.when('/products', {
    title: 'Products',
    templateUrl: '/partials/products.list.html',
    controller: 'ProductsController'
});

$routeProvider.when('/products/:id', {
    templateUrl: '/partials/products.detail.html',
    controller: 'ProductController'
});

在运行块中:

myApp.run(['$rootScope', function($rootScope) {
    $rootScope.page = {
        setTitle: function(title) {
            this.title = title + ' | Site Name';
        }
    }

    $rootScope.$on('$routeChangeSuccess', function(event, current, previous) {
        $rootScope.page.setTitle(current.$$route.title || 'Default Title');
    });
}]);

最后在控制器中:

function ProductController($scope) {
    //Load product or use resolve in routing
    $scope.page.setTitle($scope.product.name);
}

1
在ProductController的($ scope.page.setTitle)标题集是由$ rootScope覆盖在$( '$ routeChangeSuccess'在$ rootScope设置一个默认的标题上$( '$ routeChangeStart'在这方面是安全的。。
Kristo Aun 2015年

@ mr-hash:我建议这是一个很小的调整,非常适合具有许多路线但没有标题的现有角度项目。如果在路径上未定义标题,它将根据控制器的名称生成标题:$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
mikhail-t 2015年

1
记得要清理输出,就像这样:this.title = title.replace('<', '&lt;').replace('>', '&gt;').replace(' & ', ' &amp; ') + ' | Site Name';
HenrikStenbæk2015年

我收到未定义的错误,因此我将最后一位更改为:$ rootScope.page.title = current。$$ route?current。$$ route.title +'| 网站名称”:“网站名称”;
安迪

15

如果您事先知道标题,则jkoreska的解决方案是完美的,但是您可能需要根据从资源等获得的数据来设置标题。

我的解决方案需要一项服务。由于rootScope是所有DOM元素的基础,因此我们不需要像上面提到的那样在html元素上放置控制器

Page.js

app.service('Page', function($rootScope){
    return {
        setTitle: function(title){
            $rootScope.title = title;
        }
    }
});

玉器

doctype html
html(ng-app='app')
head
    title(ng-bind='title')
// ...

所有需要更改标题的控制器

app.controller('SomeController', function(Page){
    Page.setTitle("Some Title");
});

一个小问题,当您刷新页面时,在选项卡名称中看到“ {{title}}”,在页面呈现后,您只会看到“ Some Title”。工厂解决方案不具有这种行为
Dmitri Algazin 2014年

5
而是{{title}}使用ng-bind='title'
Faradox

1
同意@Faradox ...使用ng-bind防止在实际评估标题之前显示预插值语法。+100
赛斯

11

一种允许动态设置标题或元描述的干净方法。在示例中,我使用ui-router,但是您可以以相同的方式使用ngRoute。

var myApp = angular.module('myApp', ['ui.router'])

myApp.config(
    ['$stateProvider', function($stateProvider) {
        $stateProvider.state('product', {
            url: '/product/{id}',
            templateUrl: 'views/product.html',
            resolve: {
                meta: ['$rootScope', '$stateParams', function ($rootScope, $stateParams) {
                    var title = "Product " + $stateParams.id,
                        description = "Product " + $stateParams.id;
                    $rootScope.meta = {title: title, description: description};
                }]

                // Or using server side title and description
                meta: ['$rootScope', '$stateParams', '$http', function ($rootScope, $stateParams, $http) {
                    return $http({method: 'GET', url: 'api/product/ + $stateParams.id'})
                        .then (function (product) {
                            $rootScope.meta = {title: product.title, description: product.description};
                        });
                }]

            }
            controller: 'ProductController'
        });
    }]);

HTML:

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title ng-bind="meta.title + ' | My App'">myApp</title>
...

8

或者,如果您使用的是ui-router

index.html

<!DOCTYPE html>
<html ng-app="myApp">
<head>
    <title ng-bind="$state.current.data.title || 'App'">App</title>

路由

$stateProvider
  .state('home', {
      url: '/',
      templateUrl: 'views/home.html',
      data: {
        title: 'Welcome Home.'
      }
  }

2
我无法使其正常工作。我已经ui-router根据状态更新了URL和内容,并且没有收到任何错误或警告,但似乎无法通过访问状态配置对象的任何部分$state.current.[...]ui-router您使用的是哪个版本的?

我对答案的“运行时配置”编辑解决了我在上面的评论中提到的问题。:)如果有更好的方法,我很乐于接受。

这对我不起作用,并且在API文档中找不到“ title”-是否仍受支持?
GraehamF

7

定制的基于事件的解决方案

这是本文其他人尚未提及的另一种方法。

您可以像这样使用自定义事件:

// your index.html template
<html ng-app="app">
<head>
<title ng-bind="pageTitle">My App</title>

// your main app controller that is declared on the <html> element
app.controller('AppController', function($scope) {
    $scope.$on('title-updated', function(newTitle) {
        $scope.pageTitle = newTitle;
    });
});

// some controller somewhere deep inside your app
mySubmodule.controller('SomeController', function($scope, dynamicService) {
    $scope.$emit('title-updated', dynamicService.title);
});

这种方法的优点是不需要编写额外的服务,然后将其注入需要设置标题的每个控制器中,并且也不会(滥用)$rootScope。它还允许您设置动态标题(如代码示例中所示),这不能使用路由器的config对象上的自定义数据属性来实现(至少据我所知)。


5

对于您没有包含title标签的ngApp的方案,只需将服务注入需要设置窗口标题的控制器即可。

var app = angular.module('MyApp', []);

app.controller('MyController', function($scope, SomeService, Title){
    var serviceData = SomeService.get();
    Title.set("Title of the page about " + serviceData.firstname);
});

app.factory('SomeService', function ($window) {
    return {
        get: function(){
            return { firstname : "Joe" };
        }
    };
});

app.factory('Title', function ($window) {
    return {
        set: function(val){
            $window.document.title = val;
        }
    };
});

工作示例... http://jsfiddle.net/8m379/1/


5

如果您无法控制标题元素(如asp.net网络表单),则可以使用以下方法

var app = angular.module("myApp")
    .config(function ($routeProvider) {
                $routeProvider.when('/', {
                                            title: 'My Page Title',
                                            controller: 'MyController',
                                            templateUrl: 'view/myView.html'
                                        })
                            .otherwise({ redirectTo: '/' });
    })
    .run(function ($rootScope) {
        $rootScope.$on("$routeChangeSuccess", function (event, currentRoute, previousRoute) {
            document.title = currentRoute.title;
        });
    });

4

简单肮脏的方式使用$rootScope

<html ng-app="project">
<head>
<title ng-bind="title">Placeholder title</title>

在控制器中,当拥有创建标题所需的数据时,请执行以下操作:

$rootScope.title = 'Page X'

4

这些答案似乎都不足够直观,因此我创建了一个小指令来执行此操作。通过这种方式,您可以在页面中声明标题(通常是在标题处声明),并且还可以使其动态化。

angular.module('myModule').directive('pageTitle', function() {
    return {
        restrict: 'EA',
        link: function($scope, $element) {
            var el = $element[0];
            el.hidden = true; // So the text not actually visible on the page

            var text = function() {
                return el.innerHTML;
            };
            var setTitle = function(title) {
                document.title = title;
            };
            $scope.$watch(text, setTitle);
        }
    };
});

当然,您需要更改模块名称以匹配您的模块名称。

要使用它,只需将其放在视图中,就像处理常规<title>标签一样:

<page-title>{{titleText}}</page-title>

如果不需要通过动态添加纯文本,也可以只添加纯文本:

<page-title>Subpage X</page-title>

另外,您可以使用一个属性,使其对IE更友好:

<div page-title>Title: {{titleText}}</div>

您当然可以在标签中放入任何想要的文本,包括Angular代码。在此示例中,它将查找$scope.titleText自定义标题标签当前位于哪个控制器中。

只要确保您的页面上没有多个页面标题标签,否则它们会互相干扰。

此处的柱塞示例http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV。您必须下载zip并在本地运行它才能看到标题更改。


我想出了类似的东西。到目前为止,使用起来最直观,并且不需要将控制器置于html。在我的指令中,我还注入了一个可选pageTitlePrefix常量。
z0r

4

angular-ui-router的简化解决方案:

HTML:

<html ng-app="myApp">
  <head>
     <title ng-bind="title"></title>
     .....
     .....  
  </head>
</html>

App.js> myApp.config块

$stateProvider
    .state("home", {
        title: "My app title this will be binded in html title",
        url: "/home",
        templateUrl: "/home.html",
        controller: "homeCtrl"
    })

App.js> myApp.run

myApp.run(['$rootScope','$state', function($rootScope,$state) {
   $rootScope.$on('$stateChangeSuccess', function (event, toState, toParams, fromState, fromParams) {
    $rootScope.title = $state.current.title;
    console.log($state);
   });
}]);

3

这是更改标题的另一种方法。也许不像工厂功能那样可扩展(可以想象处理无限的页面),但是对我来说更容易理解:

在我的index.html中,我开始是这样的:

    <!DOCTYPE html>
      <html ng-app="app">
        <head>
          <title ng-bind-template="{{title}}">Generic Title That You'll Never See</title>

然后我制作了一个部分名称为“ nav.html”:

<div ng-init="$root.title = 'Welcome'">
    <ul class="unstyled">
        <li><a href="#/login" ng-click="$root.title = 'Login'">Login</a></li>
        <li><a href="#/home" ng-click="$root.title = 'Home'">Home</a></li>
        <li><a href="#/admin" ng-click="$root.title = 'Admin'">Admin</a></li>
        <li><a href="#/critters" ng-click="$root.title = 'Crispy'">Critters</a></li>
    </ul>
</div>

然后,我回到“ index.html”并使用ng-include和ng-view添加了nav.html:

<body class="ng-cloak" ng-controller="MainCtrl">
    <div ng-include="'partials/nav.html'"></div>
    <div>
        <div ng-view></div>
    </div>

注意到ng-cloak?它与这个答案没有任何关系,但是它会隐藏页面,直到完成加载为止,这是一种不错的感觉:)在这里了解如何:Angularjs-ng-cloak / ng-show元素闪烁

这是基本模块。我把它放在一个名为“ app.js”的文件中:

(function () {
    'use strict';
    var app = angular.module("app", ["ngResource"]);

    app.config(function ($routeProvider) {
        // configure routes
        $routeProvider.when("/", {
            templateUrl: "partials/home.html",
            controller:"MainCtrl"
        })
            .when("/home", {
            templateUrl: "partials/home.html",
            controller:"MainCtrl"
        })
            .when("/login", {
            templateUrl:"partials/login.html",
            controller:"LoginCtrl"
        })
            .when("/admin", {
            templateUrl:"partials/admin.html",
            controller:"AdminCtrl"
        })
            .when("/critters", {
            templateUrl:"partials/critters.html",
            controller:"CritterCtrl"
        })
            .when("/critters/:id", {
            templateUrl:"partials/critter-detail.html",
            controller:"CritterDetailCtrl"
        })
            .otherwise({redirectTo:"/home"});
    });

}());

如果您看模块末尾,您会发现我有一个基于:id的生物详细页面。这是Crispy Critters页面中使用的部分。[Corny,我知道-也许这是一个庆祝各种各样的鸡块的网站;这就是$ root.title更新的去向,就像您在上面的nav.html中看到的那样:

<a href="#/critters/1" ng-click="$root.title = 'Critter 1'">Critter 1</a>
<a href="#/critters/2" ng-click="$root.title = 'Critter 2'">Critter 2</a>
<a href="#/critters/3" ng-click="$root.title = 'Critter 3'">Critter 3</a>

抱歉,这么多风,但是我更喜欢提供足够详细信息的文章,以使其开始运行。请注意,AngularJS文档中的示例页面已过时,并显示了0.9版本的ng-bind-template。您可以看到它并没有太大的不同。

事后思考:您知道这一点,但其他任何人都可以在这里找到。在index.html的底部,必须在模块中包含app.js:

        <!-- APP -->
        <script type="text/javascript" src="js/app.js"></script>
    </body>
</html>

2
我的看法是,不要使用它。您正在视图(表示)中混合数据(信息)。后来这将是很难找到标题源散布在整个HTML链接可能存在在视各个地方..
阿米特bakle

由于标题仅在实际单击链接后才更新,因此当用户首次登陆页面或刷新时,标题设置不正确。
Mark Amery 2015年

3

当我不得不解决此问题时,无法将其ng-app放置在页面的html标签上,因此我通过一项服务解决了该问题:

angular.module('myapp.common').factory('pageInfo', function ($document) {

    // Public API
    return {
        // Set page <title> tag. Both parameters are optional.
        setTitle: function (title, hideTextLogo) {
            var defaultTitle = "My App - and my app's cool tagline";
            var newTitle = (title ? title : defaultTitle) + (hideTextLogo ? '' : ' - My App')
            $document[0].title = newTitle;
        }
    };

});

2

基于自定义事件的解决方案,灵感来自Michael Bromley

我无法使其与$ scope一起使用,所以我尝试了rootScope,也许更脏了……(尤其是如果您在未注册事件的页面上进行刷新)

但是我真的很喜欢事物之间如何松散耦合的想法。

我正在使用angularjs 1.6.9

index.run.js

angular
.module('myApp')
.run(runBlock);

function runBlock($rootScope, ...)
{
  $rootScope.$on('title-updated', function(event, newTitle) {
    $rootScope.pageTitle = 'MyApp | ' + newTitle;
  });
}

anyController.controller.js

angular
.module('myApp')
.controller('MainController', MainController);

function MainController($rootScope, ...)
{
  //simple way :
  $rootScope.$emit('title-updated', 'my new title');

  // with data from rest call
  TroncQueteurResource.get({id:tronc_queteur_id}).$promise.then(function(tronc_queteur){
  vm.current.tronc_queteur = tronc_queteur;

  $rootScope.$emit('title-updated', moment().format('YYYY-MM-DD') + ' - Tronc '+vm.current.tronc_queteur.id+' - ' +
                                             vm.current.tronc_queteur.point_quete.name + ' - '+
                                             vm.current.tronc_queteur.queteur.first_name +' '+vm.current.tronc_queteur.queteur.last_name
  );
 });

 ....}

index.html

<!doctype html>
<html ng-app="myApp">
  <head>
    <meta charset="utf-8">
    <title ng-bind="pageTitle">My App</title>

它为我工作:)



1

尽管其他人可能有更好的方法,但是我可以在控制器中使用$ rootScope,因为我的每个视图/模板都有一个不同的控制器。您将需要在每个控制器中注入$ rootScope。虽然这可能并不理想,但对我来说却是有效的,所以我认为我应该坚持下去。如果您检查页面,它将ng-binding添加到title标签。

控制器示例:

myapp.controller('loginPage', ['$scope', '$rootScope', function ($scope, $rootScope) {

// Dynamic Page Title and Description
$rootScope.pageTitle = 'Login to Vote';
$rootScope.pageDescription = 'This page requires you to login';
}]);

示例Index.html标头:

<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" />
<meta name="description" content="{{pageDescription}}">
<meta name="author" content="">
<link rel="shortcut icon" href="../../assets/ico/favicon.ico">
<base href="/">
<title>{{pageTitle}}</title>

您还可以将pageTitle和pageDescription设置为动态值,例如从REST调用返回数据:

    $scope.article = restCallSingleArticle.get({ articleID: $routeParams.articleID }, function() {
    // Dynamic Page Title and Description
    $rootScope.pageTitle = $scope.article.articletitle;
    $rootScope.pageDescription = $scope.article.articledescription;
});

同样,其他人可能对如何实现此目标有更好的想法,但是由于我使用的是预渲染,因此可以满足我的需求。


0

感谢Tosh shimayama的解决方案。
我认为直接将服务放入并不是很干净$scope,因此这是我的一些细微变化:http : //plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

控制器(在我的原始回答中似乎有点愚蠢)创建了一个ActionBar对象,并将其填充到$ scope中。
该对象负责实际查询服务。它还从$ scope中隐藏了设置模板URL的调用,而其他控制器可以使用该调用来设置URL。


0

迄今为止,Hash先生的答案是最好的,但是以下解决方案通过增加以下好处(对我来说)非常理想:

  • 不添加手表,这可以减慢速度
  • 实际上可以自动化我在控制器中可能完成的操作
  • 如果仍然需要,仍可以从控制器访问我。
  • 无需额外注射

在路由器中:

  .when '/proposals',
    title: 'Proposals',
    templateUrl: 'proposals/index.html'
    controller: 'ProposalListCtrl'
    resolve:
      pageTitle: [ '$rootScope', '$route', ($rootScope, $route) ->
        $rootScope.page.setTitle($route.current.params.filter + ' ' + $route.current.title)
      ]

在运行块中:

.run(['$rootScope', ($rootScope) ->
  $rootScope.page =
    prefix: ''
    body: ' | ' + 'Online Group Consensus Tool'
    brand: ' | ' + 'Spokenvote'
    setTitle: (prefix, body) ->
      @prefix = if prefix then ' ' + prefix.charAt(0).toUpperCase() + prefix.substring(1) else @prifix
      @body = if body then ' | ' + body.charAt(0).toUpperCase() + body.substring(1) else @body
      @title = @prefix + @body + @brand
])

-4

我发现更好,更动态的解决方案是使用$ watch跟踪变量更改,然后更新标题。

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.