0

我是 Angular2 的新手,正在努力通过服务更新组件视图。

我想要我的应用程序中有两种不同的页面类型。一个显示带有小徽标的标题,另一个不显示标题但具有更大的徽标。

我在根应用程序组件下有一个应用程序头组件。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();
    }

}

这是应用程序头组件:

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

      }

    });

  }

}

4

1 回答 1

1

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

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

于 2016-09-02T17:34:46.977 回答