【问题标题】:How to dynamically change header based on AngularJS partial view?如何根据AngularJS局部视图动态更改标题?
【发布时间】:2012-09-12 10:44:46
【问题描述】:

我正在使用 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"; }

【问题讨论】:

标签: javascript angularjs templates partial-views angular-routing


【解决方案1】:

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

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 属性而不是卷曲{{}},因此它们不会在加载时显示

【讨论】:

  • 对,但是您的示例没有显示如何更改由 $scope 变量参数化的 $routeChangeSuccess 上的标题,@tosh 使用 Page 服务的示例会这样做。所以你可以设置title = "Blog",但不能设置title = '{{"Blog post " + post.title}}'
  • @felix 你也可以访问像current.title 这样的标题
  • $rootScope.title = current.$route.title;没有双 $$
  • 我刚刚将我的 Angular 版本升级了几个版本(1.0.5 到 1.2.7),这让我在我的代码中崩溃了。我在旧代码中使用current.$route,它正在工作。随着升级,路线上需要双倍的美元。 current.$$route
  • 在回答时可以看到'/Product/:id'。有没有办法用这种方法获得:id 值?我尝试了title: function(params){return params.id;} 但不起作用...也许使用resolve
【解决方案2】:

您可以在&lt;html&gt; 级别定义控制器。

 <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

【讨论】:

  • uhmm... 我不确定将服务直接放入 $scope 是否在 AngularJS 架构中被认为是 nice 。或许最好在 $scope 中放入一个 Controller 函数,然后让这个函数查询服务。
  • 这个例子很棒。不过,我有一个后续行动,在初始加载时,您可以在标题中看到 {{ Page.title() }} 文本(非常快)。我认为您不能使用 ng-cloak,因为它不在体内。有什么建议可以避免这种情况吗?
  • @ArthurFrankel 只需使用 ng-bind(例如 ng-bind="Page.title()")
  • 或者我们可以在标题标签中指定控制器,不需要在 html 标题上使用全局控制器:{{ Page.title() }}
  • 我个人更喜欢在$rootScope上设置标题,而不是创建一个额外的控制器。
【解决方案3】:

注意,也可以直接用javascript设置标题,即,

$window.document.title = someTitleYouCreated;

这没有数据绑定,但是当把ng-app放在&lt;html&gt;标签有问题时就足够了。 (例如,使用 JSP 模板,其中 &lt;head&gt; 仅在一处定义,但您拥有多个应用程序。)

【讨论】:

  • 这是让我在 Internet Explorer 上运行的唯一方法,但其他方法在其他浏览器上运行
  • 正如 Maarten 所说,这是在 ie7 和 ie8 中唯一有效的方法
  • 令人惊讶的是,人们无法退后一步,看看没有范围和工厂可以轻松完成这件事
  • 难以置信。这比其他人提到的所有恶作剧要简单得多。谢谢!
  • 使用普通的“窗口”很好——它直接作用于 DOM。 '$window' 是一个有角度的东西,你必须注入它才能使用它。无论哪种方式都可以。
【解决方案4】:

html 元素上声明ng-appheadbody 提供根范围。

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

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

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

在您的页面中:

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

【讨论】:

  • 我认为的最佳答案。在这种情况下,在接受的答案中描述的 ng-app 级别的控制器是没有用的。
  • 我喜欢这个解决方案的轻量级,它避免使用 $$ 属性
  • 接受的答案增加了不必要的复杂性和风险。这个版本让它像设置一个变量一样简单。
  • 如果您死心塌地使用 $rootScope,我至少会将其提取到服务中,这样您的控制器中就没有 $rootScope。
  • 我想使用这个解决方案,但我很好奇使用它比document.title = "App"有什么优势;
【解决方案5】:

模块angularjs-viewhead 展示了一种机制,可以仅使用自定义指令在每个视图的基础上设置标题。

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

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

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

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

该指令的内容在根范围内作为viewTitle 可用,因此它可以像任何其他变量一样用于标题元素:

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

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

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

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

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

【讨论】:

  • 不敢相信这个解决方案没有得到更多的支持。其他大多数都是非常糟糕的设计选择。
  • 同意,这应该是最佳解决方案。我喜欢这比在页面级别声明一个控制器来设置标题要好得多。仅供参考:将它与 Angular v1.3.2 和 angular-route-segment v1.3.3 一起使用,它就像一个魅力。
  • 我支持这个解决方案 ;)
  • 我在我的博客上写了更多关于 angularjs-viewhead 和另一个相关的想法:apparently.me.uk/angularjs-view-specific-sidebars
  • 如果在顶层视图和子视图重用同一个视图,仍然可以使用带有 ng-if 的 view-title,例如:

    详细信息 {{...}}

    详细信息 {{ ...}}

【解决方案6】:

这是一个适合我的解决方案,它不需要将 $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);
}

【讨论】:

  • ProductController ($scope.page.setTitle) 中设置的标题被 $rootScope.$on('$routeChangeSuccess' 覆盖。在 $rootScope.$on('$routeChangeStart) 中设置默认标题' 在这方面更安全。
  • @mr-hash:这是我建议的小调整,非常适合具有许多路线但没有标题的现有 Angular 项目。如果路由上没有定义标题,它将根据控制器的名称生成标题:$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
  • 记得像这样清理输出:this.title = title.replace('&lt;', '&amp;lt;').replace('&gt;', '&amp;gt;').replace(' &amp; ', ' &amp;amp; ') + ' | Site Name';
  • 我得到未定义的错误,所以我将最后一位更改为: $rootScope.page.title = current.$$route ?当前.$$route.title + ' |网站名称' : '网站名称';
【解决方案7】:

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

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

Page.js

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

index.jade

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

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

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

【讨论】:

  • 小问题,当您刷新页面时,在标签名称中您会看到“{{ title }}”,而在页面呈现后,您只会看到“Some Title”。工厂解决方案没有这种行为
  • 而不是{{title}} 使用ng-bind='title'
  • 同意@Faradox... 使用ng-bind 可防止在标题实际计算之前显示预插值语法。 +100
【解决方案8】:

一种允许动态设置标题或元描述的简洁方式。在示例中,我使用 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>
...

【讨论】:

    【解决方案9】:

    或者,如果您使用的是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.'
          }
      }
    

    【讨论】:

    • 我无法让它工作.. 我有 ui-router 根据我的状态更新 URL 和内容,我没有收到任何错误或警告,但我似乎无法访问任何状态配置对象的一部分通过$state.current.[...]。你用什么版本的ui-router 来做这个?
    • 我对答案的“运行时配置”编辑解决了我在上面的评论中提到的问题。 :) 如果有更好的方法,我愿意接受。
    • 这对我不起作用,并且在 API 文档中找不到“标题” - 这仍然受支持吗?
    【解决方案10】:

    基于事件的自定义解决方案

    这是其他人未提及的另一种方法(在撰写本文时)。

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

    // 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);
    });
    

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

    【讨论】:

      【解决方案11】:

      对于没有包含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/

      【讨论】:

        【解决方案12】:

        如果您无法控制标题元素(如 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;
                });
            });
        

        【讨论】:

          【解决方案13】:

          使用$rootScope的简单而肮脏的方式:

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

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

          $rootScope.title = 'Page X'
          

          【讨论】:

            【解决方案14】:

            这些答案似乎都不够直观,因此我创建了一个小指令来执行此操作。这种方式允许您在页面中声明标题,通常会这样做,并且还允许它是动态的。

            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);
                    }
                };
            });
            

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

            要使用它,只需将它放在您的视图中,就像您对常规 &lt;title&gt; 标签所做的那样:

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

            如果您不需要动态,也可以只包含纯文本:

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

            或者,您可以使用属性,使其对 IE 更友好:

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

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

            请确保您的页面上没有多个页面标题标签,否则它们会相互破坏。

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

            【讨论】:

            • 我想出了类似的东西。到目前为止,使用起来最直观,并且不需要在html 上放置控制器。在我的指令中,我还注入了一个可选的pageTitlePrefix 常量。
            【解决方案15】:

            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);
               });
            }]);
            

            【讨论】:

              【解决方案16】:

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

              在我的 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 添加了 nav.html,并为我的部分添加了 ng-view:

              <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 elements blink

              这是基本模块。我把它放在一个名为“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,我知道 - 也许这是一个庆祝各种鸡块的网站;)无论如何,当用户点击任何链接时,您可以更新标题,所以在我的 Crispy Critters 主页面中,该页面通向 critter-detail 页面,这就是 $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 文档中的示例页面已过时,并显示 ng-bind-template 的 0.9 版本。你可以看到它并没有太大的不同。

              事后思考:你知道这一点,但它是为其他人准备的;在 index.html 的底部,必须在模块中包含 app.js:

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

              【讨论】:

              • 我的意见,不要用这个。您正在视图(演示文稿)中混合数据(信息)。稍后将很难找到分散在您的 HTML 链接中的标题源,这些链接可能出现在视图的不同位置。..
              • 因为标题只会在实际点击链接时更新,所以当用户第一次登陆页面或用户刷新时,这不会正确设置标题。
              【解决方案17】:

              当我不得不解决这个问题时,我无法将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;
                      }
                  };
              
              });
              

              【讨论】:

                【解决方案18】:

                基于自定义事件的解决方案灵感来自 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>
                

                它对我有用:)


                【讨论】:

                  【解决方案19】:

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

                  示例控制器:

                  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;
                  });
                  

                  同样,其他人可能对如何解决这个问题有更好的想法,但由于我使用的是预渲染,所以我的需求得到了满足。

                  【讨论】:

                    【解决方案20】:

                    感谢tosh shimayama 的解决方案。
                    我认为将服务直接放入$scope 并不那么干净,所以这是我对此的轻微改动:http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs

                    控制器(最初的答案在我看来有点太笨了)创建了一个 ActionBar 对象,这个对象被塞进了 $scope。
                    该对象负责实际查询服务。它还从 $scope 中隐藏设置模板 URL 的调用,而其他控制器可以使用它来设置 URL。

                    【讨论】:

                      【解决方案21】:

                      Mr 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
                      ])
                      

                      【讨论】:

                        【解决方案22】:

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

                        【讨论】:

                          猜你喜欢
                          • 1970-01-01
                          • 1970-01-01
                          • 2021-10-31
                          • 1970-01-01
                          • 2017-06-03
                          • 1970-01-01
                          • 1970-01-01
                          • 1970-01-01
                          相关资源
                          最近更新 更多