在Angular 2中,组件视图如何通过服务进行更新

我是Angular2的新手,我正在努力通过服务获取组件视图以进行更新 .

我想在我的应用程序中使用两种不同的页面类一个显示带有小徽标的 Headers ,另一个显示 Headers 并且具有更大的徽标 .

我在根应用程序组件下直接有一个app-header组件 . app-header组件检查服务中的数组,并使用* ngIf来更改它显示的内容 . 我附加了路由更改,因此它检查NavigationStart并使用服务相应地更新值 .

如果我点击刷新视图显示正确,但如果我在应用程序中更改路径,则视图app-header组件不会更新 . 当我在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();
    }

}

这是app-header组件:

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)

3 years ago

所以在写出这个并且问这个时我看到了我明显的错误,但我还没有看到任何其他答案,所以我仍然会发布一个答案 .

我的问题是changeDetection使用OnPush而我之前没有注意到 . 一旦设置为默认值,它就会按预期运行 .