2016-06-15 11 views
7

私は最近次のAngular 2 Read Moreコンポーネントを作成しました。このコンポーネントが果たす役割は、「続きを読む」と「読みにくい」リンクでテキストの長いブロックを崩壊させて拡大することです。文字カウントに基づくものではなく、指定された最大高さに基づいています。角2滑らかな上下のアニメーション

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> 

。ここでは、コンポーネントのスライドアップ/ダウンのアニメーションをいくつか追加して、Read Moreリンクをクリックするとコンテンツがスライドし、Less lessがクリックされるとコンテンツが指定された最大高さまでスライドするようにする必要があります。

誰でもこれを達成する方法を教えてください。

+0

[私を参照してください。ここで答える](http://stackoverflow.com/a/37843393/1375316)。この例は、まさにあなたがやろうとしていることです。 – threeve

+0

ありがとう、私は実際に上記のスタイル情報を上記のコンポーネントに追加しようとしましたが、これはうまくいかないようです。スタイル:[' div.collapsed { オーバーフロー:隠し; } '、 ' div { 移行:高さ500msの容易さ; } '] –

+0

それがうまくいくなら、私の解決策を有効にしてもよろしいですか? – Julien

答えて

2

スリーヴの答えは正しい - 唯一の問題は、CSSの移行が 'auto'では機能しないことです。したがって、ngAfterViewInit関数で自動高さを取得し、文字列として格納する必要があります。発生する可能性のある '一方向データフロー違反エラー'を止めるためにsetTimeout関数を使用することにも注意してください。

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

@Component({ 
selector: 'read-more', 
template: ` 
    <div [style.height]="isCollapsed ? maxHeight+'px' : autoHeight"> 
     <ng-content></ng-content> 
    </div> 

    <span *ngIf="isCollapsable" class="btn-link cpointer" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed? 'more':'less'}} ...</span> 

    `, 
styles: [` div { overflow-y: hidden; 
      -moz-transition: height .5s; 
      -ms-transition: height .5s; 
      -o-transition: height .5s; 
      -webkit-transition: height .5s; 
      transition: height .5s; ease;} 
     .cpointer {cursor:pointer; } 
     `] 
}) 
export class ReadMoreComponent implements AfterViewInit { 

@Input() 
maxHeight: number = 40; //two lines 

////set these to false to get the height of the expended container 
isCollapsed: boolean = false; 
isCollapsable: boolean = false; 
autoHeight: string= "auto"; 

constructor(private elementRef: ElementRef) {} 

ngAfterViewInit() { 
    // Inportant !! 
    // wait a tick to avoid one-time devMode 
    // unidirectional-data-flow-violation error 
    setTimeout(_ => { 
      let currentHeight = this.elementRef.nativeElement.getElementsByTagName('div')[0].offsetHeight; 

      this.autoHeight = currentHeight + "px"; 
      //collapsable only if the contents make container exceed the max height 
      if (currentHeight >= this.maxHeight) { 
       this.isCollapsed = true; 
       this.isCollapsable = true; 
      } 
     } 
    ); 
} 

} 
10

属性の自動計算自動化された高さの計算と

アニメーション

時々、あなたは実行時までの寸法スタイルプロパティ の値を知りません。たとえば、要素の内容と画面サイズによって幅と高さが異なることがよくあります( )。これらのプロパティは、 で、CSSでアニメーションを作成するのが難しいことがよくあります。

これらの場合、プロパティの値 が実行時に計算され、次に のアニメーションに接続されるように、特殊な*プロパティ値を使用できます。この例では

、休暇のアニメーションは、それが出て、ゼロにその高さからアニメートする前に要素 が持っているものは何でも身長取ります

animations: [ 
    trigger('shrinkOut', [ 
    state('in', style({height: '*'})), 
    transition('* => void', [ 
     style({height: '*'}), 
     animate(250, style({height: 0})) 
    ]) 
    ]) 
] 

角度の公式ドキュメントから:https://angular.io/guide/animations#automatic-property-calculation

+0

驚くばかり!これが最良の方法です! +1 – shramee

+0

これを試しましたが、要素内のテキストはアニメーション化されていませんが、何らかのバックグラウンドカラーを置くと何とかコンテナのために働きました。 –

関連する問題