首页 > 解决方案 > 无序列表中的可折叠项

问题描述

解决方案:

Nikhil 几乎得到了答案。最后我不得不创建并启动一个空数组来显示细节。我变了

return value.searchName.indexOf(this.name.toLowerCase()) != -1 ? value : null;

if (this.name.toLowerCase() == value.name.toLowerCase()) {
    this.showingDetails.push(false);
    return value;
}
else {
    return null;
}

其余的都遵循尼基尔给我的东西。

问题:

我的网站上有一个无序列表,其中包含(每个列表项)一个名称、一个链接和一段长文本。

该列表由数据库中的数据填充。因此,不知道列表中有多少项目。我无法对其进行硬编码并div为每个项目制作一个。

我想知道是否可以隐藏每个项目的长文本,并在用户单击链接时显示它。现在,我可以隐藏和显示文本,但单击“显示”将显示列表中所有项目的文本。

我在 Angular/typescript 工作,我现在拥有的是:

<ul class='list-group' *ngFor='#item of Items'>
    <li>
        <hr>
        <p><strong>{{ item.sourceType }}:</strong> <em>{{ item.sourceName }}</em></p>
        <p><strong>Link:</strong> <a target="_blank" href="{{ item.source }}">{{ item.source }}</a></p>
        <p><strong>Details:</strong> <a (click)="showDetails()">{{ showHideTxt }}</a></p>   
        <p style="white-space:pre-wrap" *ngIf="showingDetails">{{ item.details }}</p>
    </li>
</ul>

在课堂上:

items:Item[] = [];
name:string = "unknown";
foundItems:Item[];
showHideTxt:string = "show";
showingDetails:boolean = false;
itemSubscription:Subscription;

constructor(private itemService:ItemService) 
{
}   

ngOnInit()
{
    this.itemSubscription = this.itemService.getItems()
        .subscribe(
            itemData => this.items = itemData.json(),
            err => console.log(err),
            () =>   this.foundItems = this.items.filter((value)=>{
                        return value.searchName.indexOf(this.name.toLowerCase()) != -1 ? value : null
                    });
        )
    this.name = decodeURI(this.routeParams.get('name'));

    console.log(this.name.toLowerCase());
}

ngOnDestroy()
{
    this.itemSubscription.unsubscribe();
}

showDetails()
{
    this.showingDetails = !this.showingDetails
    this.showingDetails
        ?this.showHideTxt = "hide"
        :this.showHideTxt = "show";
}

标签: htmlcssangulartypescript

解决方案


在您的组件类中,创建一个布尔数组,showingDetails其中存储每个列表项的可见性状态。showHideTxt不需要属性,可以删除。

在您的 HTML 中,在调用方法时传递列表项的索引showDetails(),并在该方法中切换该索引处项目的可见性。

您的最终代码应如下所示:

组件类:

showingDetails = new Array(this.items.length).fill(false);

showDetails(index) {
    this.showingDetails[index] = !this.showingDetails[index];
}

HTML:

<ul class='list-group' *ngFor='let item of items; let i=index'>
    <li>
        <hr>
        <p><strong>{{ item.sourceType }}:</strong> <em>{{ item.sourceName }}</em></p>
        <p><strong>Link:</strong> <a target="_blank" href="{{ item.source }}">{{ item.source }}</a></p>
        <p><strong>Details:</strong> <a (click)="showDetails(i)">{{ showingDetails[i] === true ? 'Hide' : 'Show' }}</a></p>   
        <p style="white-space:pre-wrap" *ngIf="showingDetails[i]">{{ song.details }}</p>
    </li>
</ul>

编辑:

由于 HTTP 调用是异步的,items因此在订阅块之外包含数组的代码将在订阅块内的代码之前执行。这导致items数组成为undefined.

一种解决方案是将该代码移动到订阅块中,例如:

/* Other code */
...
...
showingDetails: boolean[];


ngOnInit()
{
    this.itemSubscription = this.itemService.getItems()
        .subscribe(
            itemData => this.items = itemData.json(),
            err => console.log(err),
            () =>   {
              this.foundItems = this.items.filter((value)=> {
                 return value.searchName.indexOf(this.name.toLowerCase()) != -1 ? value : null
                    });

               // initializing 'showingDetails' property inside this block
               this.showingDetails = new Array(this.foundItems.length).fill(false);
            }
        )
    this.name = decodeURI(this.routeParams.get('name'));

    console.log(this.name.toLowerCase());
}

推荐阅读