无序列表中的可折叠项

时间:2018-12-03 15:05:01

标签: html css angular typescript

解决方案:

尼希尔几乎得到了答案。最后,我必须制作并启动一个空数组以显示详细信息。我改变了

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";
}

1 个答案:

答案 0 :(得分:0)

在组件类中,创建一个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());
}