* ngFor的angular4局部变量问题

时间:2017-11-14 08:42:25

标签: angular file-upload

我有一个要求,我使用项目列表加载了多个项目。每当您上传文件时,上传文件输入都必须隐藏,该文件的详细信息必须显示为文件名和其他按钮。

我通过使用localvariable实现了场景,它可以正常使用一个项目,但是当我们有多个项目时,它不起作用。 假设我有3个itemList,如果我们点击1st item fileupload按钮并上传文件,它会加载文件名和验证按钮,但是如果我们对第2个项目进行相同的处理(在第1个进程之后),则在fileupload之后,将修改第1个文件名

查看:

<div id="userItemList" *ngFor="let item of itemList; let i=index">
    <div>
        <span>{{item.Id}}</span>
        <span>{{item.Name}}</span>
        <span>{{item.Count}}</span>
    </div>
    <div>
        <input type="file" name="UploadFile" id="fileInput" #fileInput (change)="txtUploadFile($event,i)">
        <div class="validate-file-div" #validateContent style="display:none">
            <div class="file-name" #fileName></div>
            <span id="validate-csv-button" data-program-id="0" class="button">Validate</span>
        </div>
    </div>
</div>

我的组件如下:

import { Component, OnInit, ViewChild } from '@angular/core';

@Component({
  selector: 'app-programs-manager',
  templateUrl: './ProgramsManager.component.html',
  styleUrls: ['./ProgramsManager.component.css'],
})

export class ProgramsManagerComponent implements OnInit {

    itemList = [{"Id":1,"Name":"Item1","Count":2},{"Id":2,"Name":"Item2","Count":2},{"Id":3,"Name":"Item3","Count":3}];
    @ViewChild("fileInput") fileInput;
    @ViewChild("validateContent") validateContent;
    @ViewChild("fileName") fileName;

    constructor() { }

    ngOnInit() {
    }

    txtUploadFile(event,index) {
        this.fileInput.nativeElement.style.display = "none";
        this.validateContent.nativeElement.style.display = "block";
        this.fileInput.nativeElement.innerHTML = event.target.files[0].name;
    }
}

我觉得局部变量给出了问题,但不知道如何解决它。谁能帮我。 提前致谢

2 个答案:

答案 0 :(得分:2)

您需要做的只是使用@ViewChildren而不是@ViewChild

@ViewChildren("fileInput") fileInput : QueryList<any>;
@ViewChildren("validateContent") validateContent : QueryList<any>;
@ViewChildren("fileName") fileName : QueryList<any>;

将函数txtUploadFile更改为

txtUploadFile(event,index) {
    var fileInputs = this.fileInput.toArray();
    var validateContents = this.validateContent.toArray();

    fileInputs[index].nativeElement.style.display = "none";
    validateContents[index].nativeElement.style.display = "block";
    fileInputs[index].nativeElement.innerHTML = event.target.files[0].name;
}

以下是工作示例的链接:

https://stackblitz.com/edit/angular-view-children

额外说明:

  

@ViewChild:

     

您可以使用ViewChild获取第一个元素或指令   匹配视图DOM中的选择器。如果视图DOM发生了变化,那么   一个新的孩子与选择器匹配,属性将被更新。

     

@ViewChildren:

     

您可以使用ViewChildren获取元素的QueryList或   来自视图DOM的指令。每次添加子元素时,   删除或移动后,将更新查询列表和更改   查询列表的observable将发出一个新值。

答案 1 :(得分:0)

Eliseo是对的你应该得到索引值而不是0.这就是原因。要显示和隐藏div,您必须默认创建类似showInfo = null的类变量,并使用文件数组值进行设置。

使用<button (click)="showInfo=item[index]"/>时单击下载按钮时更改值  然后在HTML中使用

<a [class.hidden]="!showInfo">Download {{item.name}} </a> 

显示现有信息