У меня есть компонент загрузки файлов, который я раскручиваю несколько экземпляров экземпляров файловых компонентов внутри на основе выбора списка файлов пользователя.
Как только пользователь загрузил n файлов в контейнер загрузки, у него есть возможность добавить некоторый текст описания для каждого компонента файла независимо, который я просто устанавливаю как строковое свойство внутри компонента файла и двустороннее связывание. к нему из HTML с ngModel
. На родительском компоненте есть кнопка, с которой начинается процесс загрузки. Я пытаюсь перебрать экземпляры файловых компонентов, которые я поместил в массив, а свойство description недоступно из родительского объекта внутри моего цикла.
Это проблема первая. Проблема вторая: я также хочу установить логическое свойство для дочернего компонента (isUploading), чтобы я мог предоставить некоторую обратную связь с пользователем, что этот конкретный файл находится в процессе выполнения. Сейчас я просто пытаюсь показать ProgressSpinner
специально для этого дочернего файлового компонента. Но это не автоматическое обновление, основанное на моем обновлении ссылки внутри цикла в родительском компоненте.
Я уверен, что мне чего-то не хватает в событиях или тому подобном, но я изо всех сил пытаюсь собрать их вместе и не могу найти хороший ресурс для своего сценария.
Вот родитель (компонент загрузки файла) ts:
import { Component, OnInit, Input } from '@angular/core';
import { MatFileComponent } from './mat-file.component';
@Component({
selector: 'mat-file-upload',
templateUrl: './mat-file-upload.component.html',
styleUrls: ['./mat-file-upload.component.css']
})
export class MatFileUploadComponent implements OnInit {
constructor() { }
fileList: MatFileComponent[]
@Input() apiEndpoint: string;
@Input() parentContainerId: string;
hasFiles: boolean;
bucketDescription: string;
addFilesToList(files: File[]): void {
this.fileList = [];
for (let file of files) {
// generate the file component here in code then bind them in the loop in the HTML
let fileComponent = new MatFileComponent()
fileComponent.fileData = file;
fileComponent.fileDescription = '';
fileComponent.fileName = file.name;
fileComponent.fileType = file.type;
this.fileList.push(fileComponent);
}
this.hasFiles = true;
}
startUpload(): void {
if (!this.fileList || !this.fileList.length || !this.hasFiles) {
return;
}
for (let fileComponent of this.fileList) {
console.log("desc: " + fileComponent.fileDescription);
fileComponent.isUploading = true;
}
}
ngOnInit() {
}
}
Вот его поддерживающий HTML:
<input type="file" hidden name="addToList" [class]="ng-hide" #file multiple id="addToList" (change)="addFilesToList(file.files)" />
<label for="addToList" class="mat-raised-button">
Select Files To Upload
</label>
<div *ngIf="fileList && fileList.length">
<mat-file *ngFor="let file of fileList"
[fileName]="file.fileName"
[fileData]="file.fileData"
[fileType]="file.fileType"
[projectId]="projectId"></mat-file>
</div>
<mat-card class="card-footer" *ngIf="hasFiles">
<mat-form-field>
<textarea matInput required placeholder="*Required* file bucket description..." [(ngModel)]="bucketDescription"></textarea>
</mat-form-field>
<button class="mat-raised-button submit-form" (click)="startUpload()" [disabled]="!bucketDescription || !bucketDescription.length > 0">
Upload Files
</button>
</mat-card>
Вот дочерний (файловый компонент) ts:
import { Component, OnInit, Input } from '@angular/core';
import { IFile } from '../Interfaces/IFile';
@Component({
selector: 'mat-file',
templateUrl: './mat-file.component.html',
styleUrls: ['./mat-file.component.css']
})
export class MatFileComponent implements OnInit, IFile {
@Input() fileName: string;
@Input() fileData: File;
@Input() fileType: string;
@Input() projectId: number;
public isUploading: boolean;
fileDescription: string;
imageLocalUrl: any;
componentLoaded: boolean = false
constructor() { }
get isFileImage(): boolean {
return this.fileType.toLowerCase().indexOf('image') > -1;
}
ngOnInit() {
var reader = new FileReader();
reader.readAsDataURL(this.fileData);
reader.onload = (event) => {
this.imageLocalUrl = reader.result;
}
this.componentLoaded = true;
}
}
И поддерживающий его HTML:
<div *ngIf="componentLoaded" class="file-card">
<mat-card class="mat-card-image">
<mat-card-subtitle>{{ fileName }}</mat-card-subtitle>
<mat-card-content>
<div *ngIf="imageLocalUrl && isFileImage" class="image-thumb file-thumb" [style.backgroundImage]="'url(' +imageLocalUrl+ ')'"></div>
<mat-form-field>
<textarea matInput placeholder="*Optional* file description..." [(ngModel)]="fileDescription"></textarea>
</mat-form-field>
</mat-card-content>
<div *ngIf="(isUploading)" class="loading-indicator-shade">
<mat-progress-spinner class="loading-indicator" mode="indeterminate"></mat-progress-spinner>
</div>
</mat-card>
</div>
И вот как я раскручиваю компонент загрузки файлов с помощью директивы tag:
<mat-file-upload [apiEndpoint]="'/api/ProjectApi/UploadFile'" [parentContainerId]="projectId"></mat-file-upload>
Я прошу прощения за весь этот код рвоты, но хотел нарисовать очень четкую картину. Я уверен, что оба предмета являются чем-то простым, но я в тупике.
ТИА