Używam ng-view, aby uwzględnić widoki częściowe AngularJS i chcę zaktualizować tytuł strony i tagi nagłówka h1 na podstawie dołączonego widoku. Są one jednak poza zakresem kontrolerów widoku częściowego, więc nie mogę wymyślić, jak powiązać je z zestawem danych w kontrolerach.
Gdyby to był ASP.NET MVC, możesz użyć @ViewBag, aby to zrobić, ale nie znam odpowiednika w AngularJS. Szukałem usług wspólnych, wydarzeń itp., Ale nadal nie mogę ich uruchomić. Jakikolwiek sposób zmodyfikowania mojego przykładu, aby działał, byłby mile widziany.
Mój 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>
Mój 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"; }
Odpowiedzi:
Możesz zdefiniować kontroler na
<html>
poziomie.Tworzysz usługę:
Page
i modyfikujesz z kontrolerów.Inject
Page
i nazywają 'Page.setTitle ()' z kontrolerami.Oto konkretny przykład: http://plnkr.co/edit/0e7T6l
źródło
$rootScope
zamiast tworzyć dodatkowy kontroler.Właśnie odkryłem dobry sposób na ustawienie tytułu strony, jeśli używasz routingu:
JavaScript:
HTML:
Edycja : użycie
ng-bind
atrybutu zamiast curlies,{{}}
aby nie wyświetlały się po załadowaniuźródło
title = "Blog"
ale nietitle = '{{"Blog post " + post.title}}'
.current.title
równieżcurrent.$route
starego kodu i działało. Wraz z aktualizacją potrzebne są podwójne $ na trasie.current.$$route
'/Product/:id'
. Czy jest jakiś sposób na uzyskanie:id
wartości za pomocą tej metody? Próbowałem,title: function(params){return params.id;}
ale nie działa ... Może używaszresolve
?Pamiętaj, że możesz również ustawić tytuł bezpośrednio za pomocą javascript, tj.
To nie ma wiązania danych, ale wystarczy, gdy umieszczenie
ng-app
w<html>
tagu jest problematyczne. (Na przykład przy użyciu szablonów JSP, gdzie<head>
jest zdefiniowane dokładnie w jednym miejscu, ale masz więcej niż jedną aplikację).źródło
Deklarowanie
ng-app
nahtml
elemencie zapewnia zasięg korzeni zarówno dlahead
ibody
.Dlatego w swoim kontrolerze wstaw
$rootScope
i ustaw właściwość nagłówka:i na twojej stronie:
źródło
document.title = "App"
;Moduł angularjs-viewhead pokazuje mechanizm ustawiania tytułu na podstawie podglądu przy użyciu tylko niestandardowej dyrektywy.
Można go zastosować do istniejącego elementu widoku, którego treść jest już tytułem widoku:
... lub może być użyty jako samodzielny element, w którym to przypadku element będzie niewidoczny w renderowanym dokumencie i zostanie użyty tylko do ustawienia tytułu widoku:
Treść tej dyrektywy jest udostępniana w zakresie głównym jako
viewTitle
, więc można jej używać w elemencie title tak jak każdej innej zmiennej:Można go również użyć w dowolnym innym miejscu, które może „zobaczyć” zakres główny. Na przykład:
To rozwiązanie umożliwia ustawienie tytułu za pomocą tego samego mechanizmu, który służy do kontrolowania pozostałej części prezentacji: szablonów AngularJS. Pozwala to uniknąć konieczności zaśmiecania kontrolerów za pomocą tej logiki prezentacji. Administrator musi udostępnić wszelkie dane, które zostaną wykorzystane do poinformowania o tytule, ale szablon ostatecznie określa sposób jego przedstawienia, i może użyć interpolacji wyrażeń i filtrów do normalnego wiązania danych zakresu.
(Uwaga: Jestem autorem tego modułu, ale odsyłam do niego tutaj tylko w nadziei, że pomoże to komuś innemu rozwiązać ten problem.)
źródło
Oto dostosowane rozwiązanie, które działa dla mnie i nie wymaga wstrzyknięcia $ rootScope do kontrolerów w celu ustawienia tytułów stron specyficznych dla zasobów.
W szablonie głównym:
W konfiguracji routingu:
I w bloku uruchamiania:
Wreszcie w kontrolerze:
źródło
$rootScope.page.setTitle(current.$$route.title || current.$$route.controller.replace('Ctrl', ''));
this.title = title.replace('<', '<').replace('>', '>').replace(' & ', ' & ') + ' | Site Name';
Rozwiązanie jkoreska jest idealne, jeśli znasz tytuły wcześniej, ale może być konieczne ustawienie tytułu na podstawie danych uzyskanych z zasobu itp.
Moje rozwiązanie wymaga jednej usługi. Ponieważ rootScope jest podstawą wszystkich elementów DOM, nie musimy umieszczać kontrolera na elemencie HTML jak ktoś wspomniany
Page.js
index.jade
Wszystkie kontrolery, które muszą zmienić tytuł
źródło
{{title}}
użyjng-bind='title'
ng-bind
zapobiega wyświetlaniu wstępnie interpolowanej składni przed faktyczną oceną tytułu. +100Czysty sposób, który umożliwia dynamiczne ustawianie tytułu lub meta opisu. Na przykład używam interfejsu użytkownika routera, ale możesz używać ngRoute w ten sam sposób.
HTML:
źródło
Alternatywnie, jeśli używasz interfejsu użytkownika routera :
index.html
Wytyczanie
źródło
ui-router
aktualizację adresu URL i zawartości w oparciu o mój stan i nie otrzymuję żadnych błędów ani ostrzeżeń, ale wydaje się, że nie mogę uzyskać dostępu do żadnej części obiektu konfiguracji stanu$state.current.[...]
. Jakiej wersjiui-router
użyłeś do tego?Niestandardowe rozwiązanie oparte na zdarzeniach
Oto inne podejście, o którym inni nie wspominali tutaj (w tym piśmie).
Możesz użyć niestandardowych zdarzeń, takich jak:
Zaletą tego podejścia jest to, że nie wymaga zapisywania dodatkowych usług, a następnie wstrzykiwania ich do każdego kontrolera, który musi ustawić tytuł, a także (ab) nie używa
$rootScope
. Pozwala także ustawić dynamiczny tytuł (jak w przykładzie kodu), co nie jest możliwe przy użyciu niestandardowych atrybutów danych w obiekcie konfiguracji routera (o ile mi wiadomo).źródło
W przypadku scenariuszy, w których nie masz aplikacji ngApp zawierającej
title
znacznik, po prostu wstrzyknij usługę do kontrolerów, które muszą ustawić tytuł okna.Przykład roboczy ... http://jsfiddle.net/8m379/1/
źródło
Jeśli nie masz kontroli nad elementem tytułowym (jak formularz internetowy asp.net), możesz skorzystać z tej opcji
źródło
Prosty i brudny sposób przy użyciu
$rootScope
:Gdy dysponujesz danymi niezbędnymi do utworzenia tytułu, w kontrolerach:
źródło
Żadna z tych odpowiedzi nie była wystarczająco intuicyjna, dlatego stworzyłem małą dyrektywę, aby to zrobić. W ten sposób możesz zadeklarować tytuł na stronie, na której normalnie byś to zrobił, a także dynamicznie.
Musisz oczywiście zmienić nazwę modułu, aby pasowała do twojej.
Aby go użyć, po prostu wyświetl to w widoku, podobnie jak w przypadku zwykłego
<title>
tagu:Możesz także dołączyć zwykły tekst, jeśli nie potrzebujesz go dynamicznie:
Możesz też użyć atrybutu, aby uczynić go bardziej przyjaznym dla IE:
Oczywiście możesz umieścić dowolny znacznik w znaczniku, w tym kod kątowy. W tym przykładzie będzie szukał
$scope.titleText
dowolnego kontrolera, w którym aktualnie znajduje się niestandardowy tag.Po prostu upewnij się, że nie masz na swojej stronie wielu tagów tytułów stron, bo inaczej się zlepią.
Przykład plunkera tutaj http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV . Musisz pobrać plik zip i uruchomić go lokalnie, aby zobaczyć zmianę tytułu.
źródło
html
. W mojej dyrektywie wprowadzam również opcjonalnąpageTitlePrefix
stałą.Uproszczone rozwiązanie dla routera kątowego:
HTML:
Blok App.js> myApp.config
App.js> myApp.run
źródło
Oto inny sposób zmiany tytułu. Może nie jest tak skalowalny jak funkcja fabryczna (która może obsługiwać nieograniczoną liczbę stron), ale łatwiej mi było zrozumieć:
W moim index.html zacząłem tak:
Następnie utworzyłem częściowy o nazwie „nav.html”:
Potem wróciłem do „index.html” i dodałem nav.html, używając ng-include i ng-view dla moich stronicujących:
Zauważ, że ng-cloak? Nie ma to nic wspólnego z tą odpowiedzią, ale ukrywa stronę, dopóki nie zakończy się ładowanie, miły akcent :) Dowiedz się, jak tutaj: Angularjs - elementy ng-cloak / ng-show migają
Oto podstawowy moduł. Umieszczam go w pliku o nazwie „app.js”:
Jeśli spojrzysz na koniec modułu, zobaczysz, że mam stronę ze szczegółami w oparciu o: id. Jest to częściowy, który jest używany ze strony Crispy Critters. [Corny, wiem - może to strona, która celebruje wszelkiego rodzaju samorodki kurczaka;) W każdym razie możesz zaktualizować tytuł, gdy użytkownik kliknie dowolny link, więc na mojej głównej stronie Crispy Critters, która prowadzi do strony ze szczegółami o stworzeniach, właśnie tam poszedłaby aktualizacja $ root.title, tak jak widzieliście w nav.html powyżej:
Przepraszam, ale wietrznie, ale wolę post, który zawiera wystarczająco dużo szczegółów, aby go uruchomić. Zauważ, że przykładowa strona w dokumentach AngularJS jest nieaktualna i zawiera wersję 0.9 ng-bind-template. Widać, że nie jest tak bardzo inaczej.
Po namyśle: wiesz o tym, ale jest tu dla każdego; na dole index.html należy dołączyć app.js do modułu:
źródło
Kiedy musiałem rozwiązać ten problem, nie mogłem umieścić tagu
ng-app
na stroniehtml
, więc rozwiązałem go za pomocą usługi:źródło
Niestandardowe rozwiązanie oparte na zdarzeniach inspirowane Michaela Bromleya
Nie byłem w stanie sprawić, aby działał z $ scope, więc spróbowałem z rootScope, może trochę bardziej brudny ... (szczególnie jeśli odświeżasz stronę, która nie rejestruje zdarzenia)
Ale bardzo podoba mi się pomysł, jak rzeczy są luźno powiązane.
Używam angularjs 1.6.9
index.run.js
anyController.controller.js
index.html
To działa dla mnie :)
źródło
Podczas gdy inni mogą mieć lepsze metody, byłem w stanie używać $ rootScope w moich kontrolerach, ponieważ każdy z moich widoków / szablonów ma inny kontroler. Musisz wprowadzić $ rootScope do każdego kontrolera. Chociaż może to nie być idealne, działa dla mnie, więc pomyślałem, że powinienem to przekazać. Jeśli przejrzysz stronę, dodasz wiązanie ng do tagu tytułu.
Przykładowy kontroler:
Przykładowy nagłówek Index.html:
Możesz także ustawić pageTitle i pageDescription na wartości dynamiczne, takie jak zwracanie danych z wywołania REST:
Znowu inni mogą mieć lepsze pomysły, jak do tego podejść, ale ponieważ używam renderowania wstępnego, moje potrzeby są zaspokojone.
źródło
Dzięki tosh shimayama za jego rozwiązanie.
Pomyślałem, że nie jest tak łatwo umieścić usługę bezpośrednio w
$scope
, więc oto moja niewielka odmiana: http://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWsKontroler (który w pierwotnej odpowiedzi wydawał mi się zbyt głupi) tworzy obiekt ActionBar, a ten jest umieszczany w $ scope.
Obiekt jest odpowiedzialny za faktyczne wysłanie zapytania do usługi. Ukrywa również przed zakresem $ wywołanie, aby ustawić adres URL szablonu, który zamiast tego jest dostępny dla innych kontrolerów, aby ustawić adres URL.
źródło
Pan Hash miał jak dotąd najlepszą odpowiedź, ale poniższe rozwiązanie czyni go idealnym (dla mnie), dodając następujące korzyści:
W routerze:
W bloku uruchamiania:
źródło
Lepszym i dynamicznym rozwiązaniem, które znalazłem, jest użycie $ watch do śledzenia zmian zmiennych, a następnie zaktualizowanie tytułu.
źródło