2016-06-14 6 views
8

각도 2로 readmore 지시문을 작성해야합니다. 이 지시문은 "더 읽기"및 "닫기"링크가있는 긴 텍스트 블록을 축소하고 확장하는 데 사용됩니다. 문자 수를 기준으로하지 않고 지정된 최대 높이를 기준으로합니다.각도 2 자세히 지시어

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

누구나이 특정 케이스의 높이를 가져 오거나 설정하는 가장 신뢰할 수있는 방법을 안내해 줄 수 있습니까?

이 지침을 어떻게 구현할 수 있는지에 대한 지침은 매우 높이 평가 될 것입니다. 내 요구 사항을 충족 아래의 구성 요소를 만들 수 있어요 Andzhik에서 도움을

:

나는이 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> 

, 제안 주시기 바랍니다.

+0

찾기 currentHeight (_ => {.....}) 일부 창을 제거 할 것 각도 실행 변경 감지 중에 크기 조정 문제가 발생합니다. http://stackoverflow.com/questions/38930183/angular2-expression-has-changed-after-ws-checked-binding-to-div-width-wi를 참조하십시오. – chenk

답변

11

Directive이 아닌 Component이 필요합니다. Components을 추가해야하므로 더 이해가됩니다. 버튼/링크 (DOM 업데이트)를 더 읽으십시오.

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

export class ReadMoreComponent { 
    isCollapsed: boolean = true; 
} 

사용법 : 내 요구 사항을 충족 아래의 구성 요소를 만들 수 있어요 Andzhik의 도움으로

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

답장을 보내 주신 Andzhik에게 감사드립니다. 템플릿 :'

Read more
' 스타일 : [' DIV 나 구성 요소의 일부를 변경했다.접힌 { 신장 : 150px; 오버플로 : 숨김; } '] 도 추가했습니다. @Input() 텍스트 : 문자열; 하지만 여전히 텍스트를 포함하는 div의 높이를 얻는 방법이 필요하므로 표시 여부에 관계없이 더 많은 링크를 읽을 것인지 결정할 수 있습니다. –

+0

'ElementRef' http://ngcourse.rangle.io/handout/advanced-components/elementref.html을 사용하면 'Component'를 나타내는 DOM 요소에 직접 액세스 할 수 있습니다. 추신 : 내 원래 답변에 만족하는 경우 동의 해주세요. 감사합니다. –

+0

나는 그것을 시도했지만 생성자 또는 ngAfterContentChecked에서 콘솔에 로그온하면 정의되지 않은 console.log (this.el.nativeElement.height)가 반환됩니다. 나는 또한 @HostBinding ('style.height') 개인 높이를 시도했다 : string; 하지만 그것도 정의되지 않았습니다. –

10

.

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> 
8

내가 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.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();  
    } 
} 

사용법 :의 setTimeout 내부

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

고마워, 그게 내가 필요한거야! – Rodney

+0

html 태그가있는 콘텐츠는 어떻습니까? –

+0

나는 그것이 html로 작동해야한다고 생각한다. [innerHTML] 지시문 – jugg1es

0
import { Component, Input,OnChanges} from '@angular/core'; 
@Component({  
    selector: 'read-more', 
    template: ` 
     <div [innerHTML]="currentText"></div> 
     <span *ngIf="showToggleButton"> 
      <a (click)="toggleView()">Read {{isCollapsed? 'more':'less'}}</a> 
     </span>` 
}) 

export class ReadMoreDirective implements OnChanges { 

    @Input('text') text: string; 
    @Input('maxLength') maxLength: number = 100; 
    @Input('showToggleButton')showToggleButton:boolean; 

    currentText: string; 

    public isCollapsed: boolean = true; 

    constructor(
     //private elementRef: ElementRef 
    ) { 

    } 
    toggleView() { 
     this.isCollapsed = !this.isCollapsed; 
     this.determineView(); 
    } 

    determineView() { 

     if (this.text.length <= this.maxLength) { 
      this.currentText = this.text; 
      this.isCollapsed = false; 
      return; 
     } 

     if (this.isCollapsed == true) { 
      this.currentText = this.text.substring(0, this.maxLength) + "..."; 
     } else if(this.isCollapsed == false) { 
      this.currentText = this.text; 
     } 

    } 

    ngOnChanges() { 
     if(!this.validateSource(this.text)) { 
      //throw 'Source must be a string.'; 
      console.error('Source must be a string.'); 
     } 
     else{ 
      this.determineView(); 
     } 
    } 

    validateSource(s) { 
     if(typeof s !== 'string') { 
      return false; 
     } else { 
      return true; 
     } 
    } 
} 

및 사용

<read-more [text]="this is test text" [maxLength]="10" [showToggleButton]="true"></read-more>