Я использую 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"; }
Ответы:
Вы можете определить контроллер на
<html>
уровне.Вы создаете сервис:
Page
и модифицируете из контроллеров.Введите
Page
и вызовите Page.setTitle () из контроллеров.Вот конкретный пример: http://plnkr.co/edit/0e7T6l
источник
$rootScope
вместо создания дополнительного контроллера.Я только что нашел хороший способ установить заголовок страницы, если вы используете маршрутизацию:
JavaScript:
HTML:
Редактировать : используя
ng-bind
атрибут вместо фигурных скобок,{{}}
чтобы они не отображались при загрузкеисточник
title = "Blog"
но неtitle = '{{"Blog post " + post.title}}'
.current.title
такжеcurrent.$route
в старом коде, и он работал. При обновлении необходим двойной $ на маршруте.current.$$route
'/Product/:id'
. Есть ли способ получить:id
значение с помощью этого метода? Я пытался,title: function(params){return params.id;}
но не работает ... Может быть, с помощьюresolve
?Обратите внимание, что вы также можете установить заголовок непосредственно с помощью JavaScript, т.е.
Это не имеет привязки данных, но достаточно , если положить
ng-app
в<html>
теге является проблематичным. (Например, при использовании шаблонов JSP, где<head>
определено ровно в одном месте, у вас есть несколько приложений.)источник
Объявление
ng-app
наhtml
элементе обеспечивает корневой простор для какhead
иbody
.Поэтому в вашем контроллере введите
$rootScope
и установите свойство заголовка для этого:и на вашей странице:
источник
document.title = "App"
;Модуль angularjs-viewhead показывает механизм для установки заголовка для каждого просмотра с использованием только пользовательской директивы.
Его можно применить к существующему элементу представления, содержимое которого уже является заголовком представления:
... или его можно использовать как отдельный элемент, в этом случае этот элемент будет невидимым в отображаемом документе и будет использоваться только для установки заголовка представления:
Содержимое этой директивы доступно в корневой области как
viewTitle
, поэтому его можно использовать в элементе title, как и в любой другой переменной:Его также можно использовать в любом другом месте, которое может «видеть» корневую область видимости. Например:
Это решение позволяет устанавливать заголовок с помощью того же механизма, который используется для управления остальной частью презентации: шаблоны AngularJS. Это позволяет избежать необходимости загромождать контроллеры этой логикой представления. Контроллер должен предоставлять любые данные, которые будут использоваться для информирования заголовка, но шаблон окончательно определяет, как его представлять, и может использовать интерполяцию выражений и фильтры для привязки к данным области как обычно.
(Отказ от ответственности: я являюсь автором этого модуля, но я ссылаюсь на него здесь только в надежде, что он поможет кому-то еще решить эту проблему.)
источник
Вот адаптированное решение, которое работает для меня, которое не требует внедрения $ rootScope в контроллеры для установки заголовков страниц для конкретных ресурсов.
В мастер-шаблоне:
В конфиге маршрутизации:
И в блоке бега:
Наконец-то в контроллере:
источник
$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
this.title = title.replace('<', '<').replace('>', '>').replace(' & ', ' & ') + ' | Site Name';
Решение jkoreska идеально подходит, если вы знаете заголовки заранее, но вам может потребоваться установить заголовок на основе данных, которые вы получаете от ресурса и т. д.
Мое решение требует одного сервиса. Поскольку rootScope является основой всех элементов DOM, нам не нужно помещать контроллер в элемент HTML, как кто-то упоминал
Page.js
index.jade
Все контроллеры, которые должны изменить заголовок
источник
{{title}}
используйтеng-bind='title'
ng-bind
предотвращает отображение предварительно интерполированного синтаксиса до того, как заголовок действительно оценивается. +100Чистый способ, который позволяет динамически устанавливать заголовок или мета-описание. В примере я использую ui-router, но вы можете использовать ngRoute таким же образом.
HTML:
источник
В качестве альтернативы, если вы используете ui-router :
index.html
Маршрутизация
источник
ui-router
обновляю URL и контент на основе своего состояния, и я не получаю ошибок или предупреждений, но я не могу получить доступ к какой-либо части объекта конфигурации состояния через$state.current.[...]
. Какую версиюui-router
вы использовали для этого?Индивидуальное решение на основе событий
Вот еще один подход, который не был упомянут другими здесь (на момент написания статьи).
Вы можете использовать пользовательские события, например, так:
Этот подход имеет то преимущество, что не требует написания дополнительных сервисов и их последующего внедрения в каждый контроллер, которому требуется установить заголовок, а также не использует (ab)
$rootScope
. Это также позволяет вам установить динамический заголовок (как в примере кода), что невозможно при использовании пользовательских атрибутов данных в объекте конфигурации маршрутизатора (насколько я знаю, по крайней мере).источник
Для сценариев, в которых у вас нет ngApp, содержащего
title
тег, просто внедрите сервис в контроллеры, которым необходимо установить заголовок окна.Рабочий пример ... http://jsfiddle.net/8m379/1/
источник
Если вы не можете контролировать элемент title (например, веб-форму asp.net), вот что вы можете использовать
источник
Простой и грязный способ использования
$rootScope
:В ваших контроллерах, когда у вас есть данные, необходимые для создания заголовка, выполните:
источник
Ни один из этих ответов не казался достаточно интуитивным, поэтому я создал небольшую директиву для этого. Этот способ позволяет вам объявить заголовок на странице, где обычно это делается, и позволяет ему быть динамичным.
Вам, конечно, нужно изменить имя модуля, чтобы оно соответствовало вашему.
Чтобы использовать это, просто бросьте это в своем представлении, так же, как вы сделали бы для обычного
<title>
тега:Вы также можете просто включить простой текст, если вам это не нужно, динамически:
Кроме того, вы можете использовать атрибут, чтобы сделать его более удобным для IE:
Вы можете поместить любой текст в тег, который вы хотите, включая угловой код. В этом примере он будет искать
$scope.titleText
в любом контроллере, в котором находится тег пользовательского заголовка.Просто убедитесь, что на вашей странице нет нескольких тегов заголовка страницы, иначе они будут слипаться.
Пример плунжера здесь http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV . Вам нужно скачать zip и запустить его локально, чтобы увидеть изменение названия.
источник
html
. В моей директиве я также добавляю необязательнуюpageTitlePrefix
константу.Упрощенное решение для angular-ui-router:
HTML:
App.js> блок myApp.config
App.js> myApp.run
источник
Вот другой способ сделать изменения названия. Возможно, не так масштабируемо, как фабричная функция (которая могла бы обрабатывать неограниченное количество страниц), но мне было легче понять:
В моем index.html я начал так:
Затем я сделал партиал под названием «nav.html»:
Затем я вернулся к «index.html» и добавил nav.html, используя ng-include и ng-view для моих партиалов:
Заметьте, что нг-плащ? Он не имеет никакого отношения к этому ответу, но он скрывает страницу до тех пор, пока она не загрузится, приятное прикосновение :) Узнайте, как здесь: Angularjs - элементы ng-cloak / ng-show мигают
Вот основной модуль. Я положил его в файл с именем "app.js":
Если вы посмотрите в конец модуля, то увидите, что у меня есть страница с подробным описанием критериев, основанная на: id. Это часть, которая используется на странице Crispy Critters. [Корни, я знаю - может быть, это сайт, который празднует все виды куриных самородков;) В любом случае, вы можете обновить заголовок, когда пользователь нажимает на любую ссылку, поэтому на моей главной странице Crispy Critters, которая ведет на страницу с подробностями о существе, вот куда пойдет обновление $ root.title, как вы видели в nav.html выше:
Извините, что так ветрено, но я предпочитаю пост, в котором достаточно подробностей, чтобы начать работу. Обратите внимание, что пример страницы в документации AngularJS устарел и показывает версию ng-bind-template 0,9. Вы можете видеть, что это не так сильно отличается.
Запоздалая мысль: вы знаете это, но это здесь для всех остальных; в нижней части index.html необходимо включить app.js с модулем:
источник
Когда мне пришлось решить эту проблему, я не мог разместить тег
ng-app
на страницеhtml
, поэтому я решил это с помощью службы:источник
Специальное решение на основе событий, вдохновленное Майклом Бромли
Я не смог заставить его работать с $ scope, поэтому я попытался с rootScope, возможно, немного более грязным ... (особенно если вы делаете обновление на странице, которая не регистрирует событие)
Но мне действительно нравится идея о том, как вещи слабо связаны.
Я использую angularjs 1.6.9
index.run.js
anyController.controller.js
index.html
Это работает для меня :)
источник
В то время как другие могут иметь лучшие методы, я смог использовать $ rootScope в своих контроллерах, так как каждый из моих представлений / шаблонов имеет отдельный контроллер. Вам нужно будет вставить $ rootScope в каждый контроллер. Хотя это может и не быть идеальным, оно работает для меня, поэтому я подумал, что должен это передать. Если вы просматриваете страницу, она добавляет привязку ng к тегу title.
Пример контроллера:
Пример заголовка Index.html:
Вы также можете установить динамические значения для pageTitle и pageDescription, например, для возврата данных из вызова REST:
Снова, у других могут быть лучшие идеи относительно того, как приблизиться к этому, но так как я использую предварительный рендеринг, мои потребности удовлетворяются.
источник
Спасибо Тошу Симаяма за его решение.
Я думал, что не очень-то чисто поставить сервис прямо в
$scope
, так что вот мое небольшое изменение: http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWsКонтроллер (который в первоначальном ответе показался мне слишком тупым) создает объект ActionBar, и этот объект помещается в $ scope.
Объект отвечает за фактический запрос сервиса. Он также скрывает от $ scope вызов для установки URL-адреса шаблона, который вместо этого доступен другим контроллерам для установки URL-адреса.
источник
У Мистера Хэша был лучший ответ, но приведенное ниже решение делает его идеальным (для меня), добавляя следующие преимущества:
В роутере:
В блоке выполнения:
источник
Лучшее и динамичное решение, которое я нашел, - это использовать $ watch для отслеживания изменений переменных, а затем обновить заголовок.
источник