2016-09-25 40 views
0

所以我一直在以電子+ Angular2應用如下:加載異步圖像從選擇目錄後,對話框

import {Component} from '@angular/core'; 
import * as fs from "fs"; 
import {ImageFile, KeepAction, RetouchAction, PrivateAction, DeleteAction} from "./components/imageFile"; 
import {remote} from 'electron'; 
import { 
    DomSanitizationService, 
     SafeUrl 
} from '@angular/platform-browser'; 
import {Observable} from "rxjs"; 


let dialog = remote.dialog; 

@Component({ 
    selector: 'app', 
    template: ` 
     <button id="openDir" (click)="openDir()">Open</button> 
     <br /> 
     <img id="processingImage" [src]="currentImg | async"/> 
     <br /> 
     <button id="nextImage" (click)="nextImage()">Next Image</button> 
    ` 
}) 

export class AppComponent { 

    dirPath: string; 
    currentImg: Observable<SafeUrl>; 
    fileSet: string[] = []; 
    currentFile: number = 0; 

    constructor(private sanitization: DomSanitizationService) { 
     this.dirPath = ""; 
     this.currentImg = Observable.of<SafeUrl>(null); 
    } 

    /** 
    * <p>Shows a dialog for opening the directory to be processed.</p> 
    * <p>After a directory is selected, it will be analyzed and all images will be loaded to be organized.</p> 
    */ 
    openDir() { 
     dialog.showOpenDialog({defaultPath: 'C:\\', properties: ['openDirectory']}, (fileNames) => { 
      //TODO assert only one file name is present 
      this.dirPath = fileNames[0]; 
      fs.readdir(this.dirPath, (e, f) => this.loadFiles(e, f)); 
     }); 
    } 

    nextImage() { 
     if (this.currentFile < this.fileSet.length - 1) { 
      this.currentFile++; 
      this.setSanitizedCurrentImage(); 
     } 
    } 

    setSanitizedCurrentImage(){ 
     let currentPath = this.fileSet[this.currentFile]; 
     this.currentImg = Observable.of(this.sanitization.bypassSecurityTrustUrl(currentPath)); 
    } 

    loadFiles(err: NodeJS.ErrnoException, files: string[]): void { 
     this.fileSet = []; 
     this.currentFile = 0; 

     files.forEach((it) => { 
      var filePath = this.dirPath + '/' + it; 

      if (fs.statSync(filePath).isFile()) { 
       this.fileSet.push(filePath); 
      } 
     }); 
     this.setSanitizedCurrentImage(); 
    } 

} 

當擊中打開按鈕,會出現一個對話框,我選擇一個目錄,嘗試加載第一張圖片setSanitizedCurrentImage()它在nextImage上工作,但不在打開的圖像上。

我想這是由於異步方法showOpenDialog()showOpenDialog(),但我無法刷新當前圖像值。

+0

我認爲它可能有一些做的'this.fileSet [this.currentFile]國家'在第一次通話。 'this.currentFile'應該是0,那麼也許你的'this.fileSet'對集合中的第一個文件做了一些奇怪的事情。 –

+0

我能夠用Promise做到,會盡快發佈結果。 – Alfergon

回答

0

我能夠使用Promise解決此問題,並在執行showOpenDialogreaddir回調後解決此問題。

TLDR

openDir() { 
     new Promise((resolve, reject) => { 
      dialog.showOpenDialog({defaultPath: 'C:\\', properties: ['openDirectory']}, (fileNames) => { 
       //TODO assert only one file name is present 
       this.dirPath = fileNames[0]; 
       fs.readdir(this.dirPath, (e, f) => { 
        this.loadFiles(e, f); 
        resolve(); 
       }); 
      }) 
     }).then(() => this.setSanitizedCurrentImage()); 
    } 

全碼:

import {Component} from '@angular/core'; 
import * as fs from "fs"; 
import {ImageFile, KeepAction, RetouchAction, PrivateAction, DeleteAction} from "./components/imageFile"; 
import {remote} from 'electron'; 
import { 
    DomSanitizationService, 
     SafeUrl 
} from '@angular/platform-browser'; 
import {Observable} from "rxjs"; 


let dialog = remote.dialog; 

@Component({ 
    selector: 'app', 
    template: ` 
     <button id="openDir" (click)="openDir()">Open</button> 
     <br /> 
     <img id="processingImage" [src]="currentImg | async"/> 
     <br /> 
     <button id="nextImage" (click)="nextImage()">Next Image</button> 
    ` 
}) 

export class AppComponent { 

    dirPath: string; 
    currentImg: Observable<SafeUrl>; 
    fileSet: string[] = []; 
    currentFile: number = 0; 

    constructor(private sanitization: DomSanitizationService) { 
     this.dirPath = ""; 
     this.currentImg = Observable.of<SafeUrl>(null); 
    } 

    /** 
    * <p>Shows a dialog for opening the directory to be processed.</p> 
    * <p>After a directory is selected, it will be analyzed and all images will be loaded to be organized.</p> 
    */ 
    openDir() { 
     new Promise((resolve, reject) => { 
      dialog.showOpenDialog({defaultPath: 'C:\\', properties: ['openDirectory']}, (fileNames) => { 
       //TODO assert only one file name is present 
       this.dirPath = fileNames[0]; 
       fs.readdir(this.dirPath, (e, f) => { 
        this.loadFiles(e, f); 
        resolve(); 
       }); 
      }) 
     }).then(() => this.setSanitizedCurrentImage()); 
    } 

    nextImage() { 
     if (this.currentFile < this.fileSet.length - 1) { 
      this.currentFile++; 
      this.setSanitizedCurrentImage(); 
     } 
    } 

    setSanitizedCurrentImage(){ 
     let currentPath = this.fileSet[this.currentFile]; 
     this.currentImg = Observable.of(this.sanitization.bypassSecurityTrustUrl(currentPath)); 
    } 

    loadFiles(err: NodeJS.ErrnoException, files: string[]): void { 
     this.fileSet = []; 
     this.currentFile = 0; 

     files.forEach((it) => { 
      var filePath = this.dirPath + '/' + it; 

      if (fs.statSync(filePath).isFile()) { 
       this.fileSet.push(filePath); 
      } 
     }); 
    } 

}