Angular - 将数据传递到组件

时间:2018-05-03 06:20:29

标签: html angular

我对Angular开发还有点新意。

我正在为一家建筑公司建立一个网站,我在一个页面上使用三个不同的组件。以下是页面当前具有的基本概要,以及我希望它做什么:

  • 项目组件包含右侧的项目列表 的页面。在所有这些项目中,选择的项目 显示在页面左侧(projectdetail.component.html)

  • 用户可以单击页面右侧的任何项目来更改所选项目。这个新的将显示在projectdetail.component.html

  • 页面的左侧
  • 在projectdetail组件中,有一个其他的迷你画廊 用户可以单击以更改主图像的图像 显示(如典型的照片幻灯片)。

  • 我现在正面临的问题:每当我点击右边的任何项目时,projectdetail.component中的主图片都不会改变面板(所有其他数据,包括地址,幻灯片中的图像等,都按照应有的方式更新);它们只有在我点击projectdetail组件中图库中的任何图像时才会发生变化。我提出的解决方案是,当您单击右侧面板上的项目时,尝试对'mainImage'(请参阅下面的代码)进行更新。我不知道如何做到这一点。

here is an illustration; only the images in the gallery update the main one, but I want the main image to update when clicking on any of the photos on the right to the photo that is shown in that project

我的项目类:

export class Project {
    id: number;
    address: string;
    images: string[];
    price: string;
    featured: boolean;
    description: string;
}

我的项目服务:

import { Injectable } from '@angular/core';
import { Project } from '../shared/project';
import { PROJECTS } from '../shared/projects';

@Injectable()

export class ProjectService {

  constructor() { }

  getProjects(): Project[] {
    return PROJECTS;
  }

  getProject(id: number): Project {
    return PROJECTS.filter((project) => (project.id === id))[0];
  }

}

不包括与问题无关的其中一个组件,它们如下:

projects.component.html

<div class="container"
  fxLayout.sm="row"
  fxLayout.xs="column">  

  <div fxFlex=60>
    <app-projectdetail [project]="selectedProject" ></app-projectdetail> 
  </div> 

  <div fxFlex=40 *ngIf="projects">
    <mat-grid-list cols="1" rowHeight="300px">
      <mat-grid-tile *ngFor="let project of projects" (click)="onSelect(project)">
        <img src="{{ project.images[0] }}">
        <mat-grid-tile-footer>
          <h1 mat-line ngDefaultControl>{{ project.address | uppercase }}</h1>
        </mat-grid-tile-footer>
      </mat-grid-tile>
    </mat-grid-list>
  </div>
</div>

projects.component.ts

import { Component, OnInit, Inject, Optional } from '@angular/core';
import { MatDialog } from '@angular/material';

import { ProjectDialogComponent } from '../project-dialog/project-dialog.component';

import { Project } from '../shared/project';
import { ProjectService } from '../services/project.service';

@Component({
  selector: 'app-projects',
  templateUrl: './projects.component.html',
  styleUrls: ['./projects.component.scss']
})

export class ProjectsComponent implements OnInit {
  projects: Project[];
  selectedProject: Project;
  image: String;
  mainImage: String;

  constructor(private projectService: ProjectService, private dialog: MatDialog) { }

  ngOnInit() {
    this.projects = this.projectService.getProjects();
    this.selectedProject = this.projectService.getProject(0);
  }

  onSelect(project: Project) {
    this.selectedProject = project;
    this.mainImage = project.images[0];
  }

}

projectdetail.component.html

<div class="container"
  fxLayout="row"
  fxLayoutGap="10px">

  <div fxFlex=100>
    <mat-card *ngIf="project">
      <img src="{{ mainImage }}" (click)="openDialog(project)">
      <mat-card-header>
        <mat-card-title><h1>{{ project.address | uppercase }}</h1></mat-card-title>
      </mat-card-header>
      <div id="preWrapper">
        <div id="imageWrapper">
          <div id="imageContainer" *ngFor="let image of project.images">
            <img src="{{ image }}" (click)="changeImage(image)" />
          </div>
        </div>
      </div>
      <mat-card-content>
        <p>{{ project.description }}</p>
      </mat-card-content>
    </mat-card>
  </div>
</div>

projectdetail.component.ts

import { Component, OnInit, Inject, Input } from '@angular/core';
import { MatDialog } from '@angular/material';

import { ProjectDialogComponent } from '../project-dialog/project-dialog.component';

import { Project } from '../shared/project';
import { ProjectService } from '../services/project.service';

@Component({
  selector: 'app-projectdetail',
  templateUrl: './projectdetail.component.html',
  styleUrls: ['./projectdetail.component.scss']
})
export class ProjectdetailComponent implements OnInit {

  @Input()
  project: Project;
  projects: Project[];
  selectedProject: Project;
  image: String;
  mainImage: String;

  constructor(private projectService: ProjectService, private dialog: MatDialog) { }

  ngOnInit() { 
    this.mainImage = this.projectService.getProject(0).images[0];
  }

  openDialog(project: Project): void {
    let dialogRef = this.dialog.open(ProjectDialogComponent, {
      data: {
        address: this.project.address,
        images: this.project.images
      }
    })
  }

  changeImage(image: String) {
    this.mainImage = image;
  }

}

1 个答案:

答案 0 :(得分:2)

您在详细信息组件中编写ngOnChange事件,然后在主页中提出更改图像的事件,

 ngOnChanges(changes: SimpleChanges) {
    for (let propName in changes) {  
        if (propName === 'project') {
           Promise.resolve(null).then(() => 
                {raise event or write code toc hange main page image});
        }
    }
}