我收到以下错误,不知道该怎么做:
(SystemJS) Unexpected directive
ViewerComponent
imported by the moduleGalleryModule
感谢您提供有关可能导致错误的任何帮助.
在主应用程序中,它导入库模块.
gallery组件将viewer组件作为子组件.
图库组件:
import {Component,NgZone,ViewChild,ElementRef} from '@angular/core'; import {Http,Response} from '@angular/http'; import { ViewerComponent } from '../viewer/viewer.component'; import 'rxjs/Rx'; interface IImage { url: string; thumbnail: string; date: string; width: number; height: number; } @Component({ selector: 'sd-gallery',templateUrl: 'gallery.component.html',styleUrls: ['gallery.component.css'] }) export class GalleryComponent {; @ViewChild('galleryContainer') galleryContainer: ElementRef; @ViewChild('asyncLoadingContainer') asyncLoadingContainer: ElementRef; thumbnailBasePath = 'assets/img/gallery/preview_xxs/'; currentIdx: number = 0; galleryBasePath: string = 'assets/img/gallery/'; showBig: boolean = false; images: any[] = [{ url: '' }]; gallery: any[] = []; imgIterations = 1; allImagesLoaded = false; // TypeScript public modifiers constructor(private _ngZone: NgZone,private http: Http) { } private ngAfterContentInit() { this.fetchDataAndRender(); } private fetchDataAndRender() { this.http.get(this.galleryBasePath + 'data.json') .map((res: Response) => res.json()) .subscribe( data => { this.images = data; this.render(); },err => console.error(err),() => undefined); } private render() { let tempRow = [this.images[0]]; let rowIndex = 0; let i = 0; for (i; i < this.imgIterations && i < this.images.length; i++) { while (this.images[i + 1] && this.shouldAddCandidate(tempRow,this.images[i + 1])) { i++; } if (this.images[i + 1]) { tempRow.pop(); } this.gallery[rowIndex++] = tempRow; tempRow = [this.images[i + 1]]; } this.scaleGallery(); if (i >= this.images.length) { this.allImagesLoaded = true; } else { this.checkForAsyncReload(); } } private shouldAddCandidate(imgRow: IImage[],candidate: IImage): boolean { let oldDifference = this.calcIdealHeight() - this.calcRowHeight(imgRow); imgRow.push(candidate); let newDifference = this.calcIdealHeight() - this.calcRowHeight(imgRow); return Math.abs(oldDifference) > Math.abs(newDifference); } private calcRowHeight(imgRow: IImage[]) { let xsum = this.calcOriginalRowWidth(imgRow); let ratio = this.getGalleryWidth() / xsum; let rowHeight = imgRow[0].height * ratio; return rowHeight; } private scaleGallery() { this.gallery.forEach((imgRow) => { let xsum = this.calcOriginalRowWidth(imgRow); if (imgRow != this.gallery[this.gallery.length - 1]) { let ratio = this.getGalleryWidth() / xsum; imgRow.forEach((img: any) => { img.width = img.width * ratio; img.height = img.height * ratio; }) } }) } private calcOriginalRowWidth(imgRow: IImage[]) { let xsum = 0; imgRow.forEach((img) => { let individualRatio = this.calcIdealHeight() / img.height; img.width = img.width * individualRatio; img.height = this.calcIdealHeight(); xsum += img.width + 1; }); return xsum; } private calcIdealHeight() { return (this.getGalleryWidth() / 8) + 70; } private openImageViewer(img: any) { this.showBig = undefined; this.showBig = true; this.currentIdx = this.images.indexOf(img); } private getGalleryWidth() { if (this.galleryContainer.nativeElement.clientWidth === 0) { // IE11 return this.galleryContainer.nativeElement.scrollWidth; } return this.galleryContainer.nativeElement.clientWidth; } private checkForAsyncReload() { if (!this.allImagesLoaded) { var loadingDiv: any = this.asyncLoadingContainer.nativeElement; var elmTop = loadingDiv.getBoundingClientRect().top; var elmBottom = loadingDiv.getBoundingClientRect().bottom; var isVisible = (elmTop >= 0) && (elmBottom <= window.innerHeight); if (isVisible) { this.imgIterations += 5; this.fetchDataAndRender(); } } } private onClose() { this.showBig = false; } private onResize() { this.render(); } }
图库模块:
import { BrowserModule } from '@angular/platform-browser'; import { NgModule } from '@angular/core'; import { FormsModule } from '@angular/forms'; import { HttpModule } from '@angular/http'; import { ViewerComponent } from '../viewer/viewer.component'; import { GalleryComponent } from './gallery.component'; @NgModule({ imports: [BrowserModule,FormsModule,HttpModule,ViewerComponent],declarations: [GalleryComponent],exports: [GalleryModule],providers: [] }) export class GalleryModule { }
查看器HTML:
<div class="outerContainer" (window:resize)="onResize($event)" [hidden]="!showViewer"> <img [ngClass]="{'activeArrow': leftArrowActive}" class="arrow left" [src]="arrows[0]" (click)="navigate(-1,false)" [hidden]="!showViewer || !leftArrowVisible" /> <img [ngClass]="{'activeArrow': rightArrowActive}" class="arrow right" [src]="arrows[1]" (click)="navigate(1,false)" [hidden]="!showViewer || !rightArrowVisible" /> <div class="buttonContainer" [hidden]="!showViewer"> <span class="action fullsize" (click)="openFullsize()" [hidden]="!showViewer">100%</span> <img class="action close" src="assets/img/icon/close.svg" (click)="closeViewer()" [hidden]="!showViewer" /> </div> <div class="imageContainer" (click)="showNavigationArrows()" (swipeleft)="navigate(1,true)" (swiperight)="navigate(-1,true)" [hidden]="!showViewer"> <img class="image" [src]="previewImagePath" [hidden]="!showViewer" /> </div> </div>
查看器组件:
import {Component,ElementRef,Input,Output,EventEmitter} from '@angular/core'; import {Http,Response} from '@angular/http'; import 'rxjs/Rx'; interface IImage { url: string; thumbnail: string; date: string; width: number; height: number; } @Component({ selector: 'sd-viewer',templateUrl: 'viewer.component.html',styleUrls: ['viewer.component.css'] }) // host: { // '(document:keydown)': 'onKeydown($event)',// } export class ViewerComponent { @Input() images: any[]; @Input() currentIdx: number; @Input() showViewer: boolean; @Output() onClose = new EventEmitter<boolean>(); arrows: string[] = ['assets/img/icon/left.svg','assets/img/icon/right.svg']; leftArrowActive: boolean = true; rightArrowActive: boolean = true; leftArrowVisible: boolean = true; rightArrowVisible: boolean = true; previewImagePath = ''; // TypeScript public modifiers constructor(private _ngZone: NgZone,private http: Http) { } ngOnChanges(changes: any) { if (this.images[this.currentIdx].name) { this.updatePreviewImage(); } } ngAfterContentInit() { } onKeydown(event: KeyboardEvent) { let prevent = [37,39,27] .find(no => no === event.keyCode); if (prevent) event.preventDefault(); switch (prevent) { case 37: // navigate left this.navigate(-1,false); break; case 39: // navigate right this.navigate(1,false); break; case 27: // esc this.closeViewer(); break; } } updateArrowActivation() { if (this.currentIdx <= 0) { this.leftArrowActive = false; } else { this.leftArrowActive = true; } if (this.currentIdx >= this.images.length - 1) { this.rightArrowActive = false; } else { this.rightArrowActive = true; } } /** * direction (-1: left,1: right) * swipe (user swiped) */ navigate(direction : number,swipe : boolean) { if ((direction === 1 && this.currentIdx < this.images.length - 1) || (direction === -1 && this.currentIdx > 0)) { // increases or decreases the counter this.currentIdx += direction; if (swipe) { this.hideNavigationArrows(); } else { this.updateArrowActivation(); this.showNavigationArrows(); } this.updatePreviewImage(); } } hideNavigationArrows() { this.leftArrowVisible = false; this.rightArrowVisible = false; } showNavigationArrows() { this.leftArrowVisible = true; this.rightArrowVisible = true; } openFullsize() { window.location.href = 'assets/img/gallery/raw/' + this.images[this.currentIdx].name; } private closeViewer() { this.showViewer = false; this.onClose.emit(false); } private updatePreviewImage() { let height = window.innerHeight; let basePath = 'assets/img/gallery/'; if (height <= 375) { basePath += 'preview_xxs/'; } else if (height <= 768) { basePath += 'preview_xs/'; } else if (height <= 1080) { basePath += 'preview_s/'; } else if (height <= 1600) { basePath += 'preview_m/'; } else if (height <= 2160) { basePath += 'preview_l/'; } else if (height <= 2880) { basePath += 'preview_xl/'; } else { basePath += 'raw'; } this.previewImagePath = basePath + this.images[this.currentIdx].name; } private onResize() { this.updatePreviewImage(); } }
将ViewerComponent从GalleryModule的导入移动到声明.只能将模块添加到模块的导入中.组件,指令和管道放在模块的声明中:
@NgModule({ imports: [BrowserModule,HttpModule],declarations: [GalleryComponent,providers: [] }) export class GalleryModule { }
检查Angular 2 Modules以获取更多信息.