ウェブサイト検索

TypeScript - Angular 2 もっと読むディレクティブ


私はAngular2でreadmoreディレクティブを作る必要があります。このディレクティブは、長いテキストのブロックを「続きを読む」と「閉じる」リンクで折りたたんだり展開したりするために使われます。文字数ではなく、指定された最大高さに基づいて動作します。

<div read-more [maxHeight]="250px" [innerHTML]="item.details">
</div>

この特定のケースで要素の高さを取得/設定する最も信頼できる方法について、誰か教えていただけますか。

この特定の指令をどのように実施できるかについてのガイドラインも非常にありがたいです。

私はこれのようなものを作る必要があります https://github.com/jedfoster/Readmore.js

解決策:

アンドジクの助けを借りて、私の要件を満たす以下のコンポーネントを作成することができました。

import { Component, Input, ElementRef, AfterViewInit } from '@angular/core';

@Component({
    selector: 'read-more',
    template: `
        <div [innerHTML]="text" [class.collapsed]="isCollapsed" [style.height]="isCollapsed ? maxHeight+'px' : 'auto'">
        </div>
            <a *ngIf="isCollapsable" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed? 'more':'less'}}</a>
    `,
    styles: [`
        div.collapsed {
            overflow: hidden;
        }
    `]
})
export class ReadMoreComponent implements AfterViewInit {

    //the text that need to be put in the container
    @Input() text: string;

    //maximum height of the container
    @Input() maxHeight: number = 100;

    //set these to false to get the height of the expended container 
    public isCollapsed: boolean = false;
    public isCollapsable: boolean = false;

    constructor(private elementRef: ElementRef) {
    }

    ngAfterViewInit() {
        let currentHeight = this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight;
       //collapsable only if the contents make container exceed the max height
        if (currentHeight > this.maxHeight) {
            this.isCollapsed = true;
            this.isCollapsable = true;
        }
    }
}

使用法:

<read-more [text]="details" [maxHeight]="250"></read-more>

もし何か改善点があれば、遠慮なく提案してください。

回答 #1

私はdivのサイズではなく文字数を使うバージョンを作りました。

import { Component, Input, ElementRef, OnChanges} from '@angular/core';

@Component({    
    selector: 'read-more',
    template: `
        <div [innerHTML]="currentText">
        </div>
            <a [class.hidden]="hideToggle" (click)="toggleView()">Read {{isCollapsed? 'more':'less'}}</a>
    `
})

export class ReadMoreComponent implements OnChanges {
    @Input() text: string;
    @Input() maxLength: number = 100;
    currentText: string;
    hideToggle: boolean = true;

    public isCollapsed: boolean = true;

    constructor(private elementRef: ElementRef) {

    }
    toggleView() {
        this.isCollapsed = !this.isCollapsed;
        this.determineView();
    }
    determineView() {
        if (!this.text || this.text.length <= this.maxLength) {
            this.currentText = this.text;
            this.isCollapsed = false;
            this.hideToggle = true;
            return;
        }
        this.hideToggle = false;
        if (this.isCollapsed == true) {
            this.currentText = this.text.substring(0, this.maxLength) + "...";
        } else if(this.isCollapsed == false)  {
            this.currentText = this.text;
        }

    }
    ngOnChanges() {
        this.determineView();       
    }
}

使用法:

<read-more [text]="text" [maxLength]="100"></read-more>

回答 #2

私はあなたが Directive ではなく Component が必要だと思います。DOM を更新する必要がある、つまり 続きを読む ボタン/リンクを追加する必要があるので、Components の方が理にかなっています。

@Component({
    selector: 'read-more',
    template: `
        <div [class.collapsed]="isCollapsed">
            <ng-content></ng-content>
        </div>
        <div (click)="isCollapsed = !isCollapsed">Read more</div>
    `,
    styles: [`
        div.collapsed {
            height: 250px;
            overflow: hidden;
        }
    `]
})

export class ReadMoreComponent {
    isCollapsed = true;
}

使用法:

<read-more>
   <!-- you HTML goes here -->
</read-more>

回答 #3

アンドジクの助けを借りて、私は自分の要件を満たす以下のコンポーネントを作ることができました。

import { Component, Input, ElementRef, AfterViewInit } from '@angular/core';

@Component({
    selector: 'read-more',
    template: `
        <div [innerHTML]="text" [class.collapsed]="isCollapsed" [style.height]="isCollapsed ? maxHeight+'px' : 'auto'">
        </div>
            <a *ngIf="isCollapsable" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed? 'more':'less'}}</a>
    `,
    styles: [`
        div.collapsed {
            overflow: hidden;
        }
    `]
})
export class ReadMoreComponent implements AfterViewInit {

    //the text that need to be put in the container
    @Input() text: string;

    //maximum height of the container
    @Input() maxHeight: number = 100;

    //set these to false to get the height of the expended container 
    public isCollapsed: boolean = false;
    public isCollapsable: boolean = false;

    constructor(private elementRef: ElementRef) {
    }

    ngAfterViewInit() {
        let currentHeight = this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight;
       //collapsable only if the contents make container exceed the max height
        if (currentHeight > this.maxHeight) {
            this.isCollapsed = true;
            this.isCollapsable = true;
        }
    }
}

使用法:

<read-more [text]="details" [maxHeight]="250"></read-more>

関連記事