source

각도에 따라 헤더를 동적으로 변경하는 방법JS 부분 뷰?

factcode 2022. 12. 5. 21:15
반응형

각도에 따라 헤더를 동적으로 변경하는 방법JS 부분 뷰?

Angular를 포함하기 위해 ng-view를 사용하고 있습니다.JS 부분 뷰와 포함된 뷰를 기반으로 페이지 제목과 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>

My 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:

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 .{{}}가 되지 않는다.

는 '컨트롤러'에서 정의할 수 .<html>levelcontractions level level 。

 <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'입니다.

다음은 구체적인 예를 제시하겠습니다.

javascript를 사용하여 직접 제목을 설정할 수도 있습니다.

$window.document.title = someTitleYouCreated;

은 데이터 바인딩은 , 이 합니다.ng-app <html>가 있습니다를 들어 JSP JSP 템플릿은 다음과 같습니다.<head>하게 한 되어 있지만 .)

ng-app html는 두 루트 합니다.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>

module 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>

이 솔루션에서는 프레젠테이션의 나머지 부분을 제어하는 것과 동일한 메커니즘을 통해 제목을 설정할 수 있습니다.각진JS 템플릿이렇게 하면 컨트롤러를 이 프레젠테이션 로직으로 복잡하게 만들 필요가 없어집니다.컨트롤러는 제목을 알리기 위해 사용되는 모든 데이터를 사용할 수 있도록 해야 하지만 템플릿이 이 데이터를 표시하는 방법을 최종 결정하며 식 보간 및 필터를 사용하여 정상적으로 스코프 데이터에 바인딩할 수 있습니다.

(면책자:제가 이 모듈의 저자입니다만, 이 모듈을 참조하는 것은, 다른 사람이 이 문제를 해결하는 데 도움이 될 것이라는 희망에 의한 것입니다.)

리소스별 페이지 제목을 설정하기 위해 컨트롤러에 $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);
}

사전에 제목을 알고 있다면 jkoreska의 솔루션은 완벽하지만, 자원 등에서 얻은 데이터를 바탕으로 제목을 설정해야 할 수도 있습니다.

내 솔루션에는 단일 서비스가 필요합니다.rootScope는 모든 DOM 요소의 베이스이기 때문에 언급한 것처럼 html 요소에 컨트롤러를 둘 필요는 없습니다.

페이지.js

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

index.displaces를 표시합니다.

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

제목을 변경해야 하는 모든 컨트롤러

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

제목 또는 메타 설명을 동적으로 설정할 수 있는 깔끔한 방법입니다.예를 들어, 저는 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>
...

또는 ui-router를 사용하는 경우:

index.displaces를 표시합니다.

<!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.'
      }
  }

커스텀 이벤트 기반 솔루션

여기에서는 (이 글에서) 다른 사람이 언급하지 않은 또 다른 접근법이 있습니다.

다음과 같은 커스텀이벤트를 사용할 수 있습니다.

// 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또, 동적 타이틀(코드 예시와 같이)을 설정할 수도 있습니다.이것은 라우터의 설정 오브젝트에 커스텀데이터 어트리뷰트를 사용할 수 없습니다(적어도 제가 아는 한).

ngApp이 않은 의 경우 ngApp이 포함되어 .title창 titletag: 를 가 있는 만 하면 됩니다.

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/

제목 요소(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;
        });
    });

하고 으로 ★★★★★★★★★★★★★★★★★★★★★★★★★★★★」$rootScope:

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

컨트롤러에서 제목을 작성하기 위해 필요한 데이터가 있는 경우 다음을 수행합니다.

$rootScope.title = 'Page X'

이 답변들 중 어느 것도 충분히 직관적이지 않아 보여서 저는 이것을 하기 위한 작은 지시를 만들었습니다.이 방법을 사용하면, 통상 사용하는 페이지의 제목을 선언할 수 있습니다.또, 동적인 것도 가능하게 됩니다.

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>

dynamic에 의해 필요하지 않은 경우 일반 텍스트를 포함할 수도 있습니다.

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

또, 어트리뷰트를 사용하고, IE 를 보다 사용하기 쉽게 할 수도 있습니다.

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

Angular 코드를 포함하여 원하는 텍스트를 태그에 넣을 수 있습니다.예에서는 ''를 찾습니다.$scope.titleText커스텀 스위칭태그가 현재 있는 컨트롤러 중 어느 쪽이든.

페이지에 페이지 제목 태그가 여러 개 붙어 있지 않은지 확인하십시오. 그렇지 않으면 서로 엉킬 수 있습니다.

http://plnkr.co/edit/nK63te7BSbCxLeZ2ADHV의 플런커의 예를 나타냅니다.제목 변경을 확인하려면 zip을 다운로드하여 로컬로 실행해야 합니다.

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

제목 변경을 위한 다른 방법이 있습니다.공장 기능(무제한 페이지를 처리할 수 있음)만큼 확장성이 높지 않을 수도 있지만, 저는 다음과 같이 이해하기 쉬웠습니다.

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에 기반한 critter-detail 페이지가 나타납니다.Crispy Critters 페이지에서 사용하는 부분적인 것입니다.[Corny, I knugets - 모든 종류의 치킨 너겟을 기념하는 사이트일 수도 있습니다]어쨌든 사용자가 어떤 링크를 클릭해도 제목을 갱신할 수 있습니다.따라서 크리터 상세 페이지로 연결되는 메인 Crispy Criters 페이지에서 $root가 바로 여기에 있습니다.타이틀 갱신은 위의 네비게이션에서 보셨듯이 진행됩니다.

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

바람이 많이 불어서 죄송하지만, 저는 게시물이 잘 작동되도록 하기 위해 충분한 세부 정보를 제공하는 게시물을 선호합니다.Angular의 예제 페이지는JS docs는 최신 버전이 아니며 ng-bind-template의 0.9 버전을 보여줍니다.크게 다르지 않다는 것을 알 수 있습니다.

잘 알고 계시겠지만, index.html의 하단에 app.js를 모듈에 포함해야 합니다.

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

할 때, 나는 걸어, the the the the the the the the the 를 넣을 수 ng-app의 the 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;
        }
    };

});

마이클 브롬리에서 영감을 얻은 커스텀 이벤트 기반 솔루션

$scope로 동작시킬 수 없었기 때문에 rootScope로 시도했습니다.좀 더 지저분할지도 모르지만...(특히 이벤트를 등록하지 않은 페이지에서 새로 고친 경우)

하지만 나는 사물이 느슨하게 결합되어 있다는 생각이 정말 마음에 든다.

angularjs 1.6.9를 사용하고 있습니다.

index.run.syslog

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.displaces를 표시합니다.

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

효과가 있습니다. :)


다른 방법보다 나은 방법이 있을 수 있지만, 각 뷰/템플릿에는 별도의 컨트롤러가 있기 때문에 컨트롤러에서 $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;
});

다시 말씀드리지만, 다른 사람들은 어떻게 접근해야 할지 더 나은 아이디어를 가지고 있을 수 있지만, 저는 프리렌더링을 사용하고 있기 때문에 제 요구는 충족되고 있습니다.

시마야마 토시(島山 shim)의 해결 덕분이다.
를 바로 i i i i i i i i i i i i i i i i i i i i i i i i i i i i i 。$scopehttp://plnkr.co/edit/QJbuZZnZEDOBcYrJXWWs에서 조금 다른 설명을 해드리겠습니다.

컨트롤러(원래 답변에서는 너무 멍청해 보였다)는 ActionBar 객체를 만들고, 이것은 $scope에 채워집니다.
오브젝트는 실제로 서비스를 쿼리합니다.또한 템플릿 URL을 설정하기 위한 콜을 $scope에서 숨깁니다.이 콜은 다른 컨트롤러에서 URL을 설정할 수 있습니다.

지금까지의 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
])

제가 찾은 보다 우수하고 역동적인 솔루션은 $watch를 사용하여 변수 변경을 추적하고 제목을 업데이트하는 것입니다.

언급URL : https://stackoverflow.com/questions/12506329/how-to-dynamically-change-header-based-on-angularjs-partial-view

반응형