2016-09-02 92 views
0

我是Angular2的新手,我正努力通過服務獲取組件視圖。在Angular 2中如何通過服務更新組件視圖

我想在我的應用程序中使用兩種不同的頁面類型。一個顯示帶有小標誌的標題,另一個不顯示標題並具有更大的徽標。

我有一個應用程序頭組件直接在根應用程序組件下。應用程序頭組件檢查服務中的數組,並使用* ngIf來更改它顯示的內容。我附加到路由更改,以便檢查NavigationStart並使用服務相應地更新值。

如果我點擊刷新視圖顯示正確,但如果我在應用程序內更改路線視圖應用程序頭組件不會更新。當我console.log的值,我看到服務值和組件類屬性正在改變,但在組件視圖內沒有更新。我雖然也許我有這個服務的多個實例,但我在服務上添加了一個隨機數來檢查,並且它都是相同的實例。

這裏是模板的服務:

import 'rxjs/add/observable/merge'; 
 
import 'rxjs/add/operator/switchMap'; 
 

 
import { Injectable } from '@angular/core'; 
 
import { Template } from './template' 
 

 
//HANDLE TEMPLATES IN AN ORGANIZED WAY 
 
@Injectable() 
 
export class TemplateService { 
 

 
    template: Template = { 
 
     showHeader: true, 
 
     imagePath: "", 
 
     name: Math.random() 
 
    }; 
 

 
    public setShowHeader(value:boolean){ 
 
     this.template.showHeader = value; 
 
     console.log(value, this.template.showHeader);//CHECK TO MAKE SURE VALUES MATCH 
 
     console.log("name", this.template.name);//CHECK TO MAKE SURE SAME INSTANCE 
 
    } 
 

 
    //ALLOW BACKGROUND TO BE MANUALLY SET IF DESIRED - NOT USED FOR NOW 
 
    public setImage(url){ 
 
     this.template.imagePath = url; 
 
    } 
 

 
    //WHEREVER A ROUTE IS DEFINED A PAGE CAN CALL THIS SERVICE AND ADD SPECIFY AS THIS TEMPLATE 
 
    public noHeadRoutes = []; 
 

 
    public setRandomImage(){ 
 
     this.template.imagePath = this.availableImagePaths[Math.floor(Math.random() * this.availableImagePaths.length)]; 
 
    } 
 

 
    //USE THESE IF NO MANUAL IMAGE IS SET 
 
    private availableImagePaths:[string] = [ 
 
     "images/home/globe.jpg", 
 
     "images/home/typing.jpg" 
 
    ]; 
 

 
    constructor() { 
 
     this.setRandomImage(); 
 
    } 
 

 
}

這裏是應用頭組件:在寫這篇

import { ChangeDetectionStrategy, Component, EventEmitter, Input, Output, OnInit } from '@angular/core'; 
 
import { Router, NavigationStart } from '@angular/router'; 
 
import { TemplateService, Template } from '../services/template'; 
 

 
@Component({ 
 
    changeDetection: ChangeDetectionStrategy.OnPush, 
 
    selector: 'app-header', 
 
    styles: [ 
 
    require('./app-header.scss') 
 
    ], 
 
    template: ` 
 
    {{ [(template.showHeader)] }} -- {{ template.name }} 
 
    <header class="header" *ngIf="template.showHeader"> 
 
     <nav class="navbar navbar-fixed-top bg-inverse navbar-dark"> 
 
     <a class="navbar-brand" Routerlink="/" RouterLinkActive="/"> 
 
      <img src="../../images/logo.svg" class="app-logo" /> 
 
     </a> 
 
     
 
     <ul class="nav navbar-nav pull-right"> 
 
      <li class="nav-item" *ngIf="authenticated"> 
 
       <a class="nav-link" (click)="signOut.emit()" href="#"> 
 
        Sign out 
 
       </a> 
 
      </li> 
 
      <li class="nav-item" *ngIf="!authenticated"> 
 
       <a class="nav-link" Routerlink="/login" RouterLinkActive="active"> 
 
        Login 
 
       </a> 
 
      </li> 
 
     </ul> 
 
     
 
     </nav> 
 
    </header> 
 
    
 
    <!-- PUT IN A BACKGROUND IMAGE AND ADJUST SPACING --> 
 
    <div *ngIf="!template.showHeader"> 
 
     <style type="text/css"> 
 
      .hey{font-size:10px;} 
 
      
 
     </style> 
 
     <div class="big-logo"> 
 
      <img src="images/logo.svg" /> 
 
     </div> 
 
    </div> 
 
    ` 
 
}) 
 

 
export class AppHeaderComponent implements OnInit{ 
 

 
    @Input() authenticated: boolean; 
 
    @Output() signOut = new EventEmitter(false); 
 
    template: Template; 
 

 
    constructor(private _router: Router, private _ts: TemplateService) { 
 

 
    this.template = _ts.template; 
 

 
    } 
 

 
    ngOnInit(){ 
 
    //ALL VIEWS CAN SET A NO HEAD TEMPLATE IF NEEDED. THIS CHECKS AT NAVIGATION START AND SETS THE HEADER 
 
    this._router.events.subscribe((event) =>{ 
 

 
     if(event instanceof NavigationStart) { 
 

 
     if(this._ts.noHeadRoutes.includes(event.url)){ 
 
      this._ts.setShowHeader(false); 
 
     } 
 

 
     else{ 
 
      this._ts.setShowHeader(true); 
 
     } 
 

 
     } 
 

 
    }); 
 

 
    } 
 

 
}

回答

1

所以出去問這個,我看到了我明顯的錯誤,但我還沒有看到任何其他答案,所以我仍然會發表一個答案。

我的問題是changeDetection使用OnPush,我以前沒有注意到。一旦設置爲默認值,其行爲如預期。

相關問題