我需要建立一个Angular2指令readmore。什么这个指令会做的就是崩溃和扩大大段文字为“阅读”和“关闭”链接。不是字符数的基础上,但指定的最大高度的基础上。
<div read-more [maxHeight]="250px" [innerHTML]="item.details">
</div>
任何人都可以请指导什么是最可靠的方式获取/设置元素的高度,这种特殊情况下。
在这个特定的指令中如何实现的任何准则也将高度赞赏。
我需要建立这样的事情https://github.com/jedfoster/Readmore.js
解:
从Andzhik的帮助下,我能够建立以下组件,符合我的要求。
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>
如果有可能的任何改进,请随时提出。
我认为你需要一个Component
而不是Directive
。 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 = true;
}
用法:
<read-more>
<!-- you HTML goes here -->
</read-more>
lineheight
和小的计算和一些CSS text-overflow: ellipsis;
做这件工作。
.descLess {
margin-bottom: 10px;
text-overflow: ellipsis;
overflow: hidden;
word-wrap: break-word;
display: -webkit-box;
line-height: 1.8; <==== adjust line-height...a/q to your need
letter-spacing: normal;
white-space: normal;
max-height: 52px; <==== 250px etc:-
width: 100%;
/* autoprefixer: ignore next */
-webkit-line-clamp: 2; <==== clamp line 2...or 3 or 4 or 5...
-webkit-box-orient: vertical;
}
<div class="col-12 rmpm">
<div id="descLess" *ngIf="seeMoreDesc === 'false'" class="descLess col-12 rmpm">
{{inputData?.desc}}
</div>
<div *ngIf="seeMoreDesc === 'true'" class="col-12 rmpm" style="margin-bottom: 10px;line-height: 1.8;">
<!--Use Line height here-->
{{inputData?.desc}}
</div>
<span class="seeMore" *ngIf="seeMoreDesc === 'false' && lineHeightDesc > 21"
(click)="updateSeeMore('seeMoreDesc', 'true')">
See More
</span>
<span class="seeMore" *ngIf="seeMoreDesc === 'true'"
(click)="updateSeeMore('seeMoreDesc', 'false')">
See Less
</span>
</div>
declare const $:any;
seeMoreDesc = 'false';
seeMore = '';
inputData = {
'desc':'Lorem Ipusme dummy text..................'
}
constructor(
private eRef: ElementRef,
private cdRef : ChangeDetectorRef
) {}
ngAfterViewChecked() {
// pass line height here
this.lineHeightDesc = (Number($('#descLess').height()) / 1.8);
this.cdRef.detectChanges();
}
public updateSeeMore(type, action) {
if (type === 'seeMoreDesc') {
this.seeMoreDesc = action;
this.cdRef.detectChanges();
} else if (type === 'seeMore') {
this.seeMore = action;
this.cdRef.detectChanges();
}
}
我做了使用字符长度,而不是格大小的版本。
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>
从Andzhik的帮助下,我能够建立以下组件,符合我的要求。
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>
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>
如果你想在不切断任何字来显示文本字符的最大数量,更改这一行代码:
this.currentText = this.text.substring(0, this.maxLength) + "...";
至:
this.currentText = this.text.substring(0, this.maxLength);
this.currentText = this.currentText.substr(0, Math.min(this.currentText.length, this.currentText.lastIndexOf(" ")))
this.currentText = this.currentText + "..."
的@Andrei Zhytkevich代码只是略有改善(适用于降价)
import {
Component,
AfterViewInit,
ViewChild,
ElementRef,
Attribute,
ChangeDetectionStrategy } from '@angular/core';
@Component({
changeDetection: ChangeDetectionStrategy.OnPush,
selector: 'ui-read-more',
template: `
<div [class.collapsed]="isCollapsed" [style.height]="_height">
<div #wrapper>
<ng-content></ng-content>
</div>
</div>
<div class="read-more">
<button
type="button"
class="btn btn-light" (click)="onIsCollapsed()">{{isCollapsed ? 'More' : 'Less'}}</button>
</div>
`,
styles: [`
:host{
display: block;
}
.collapsed {
overflow: hidden;
padding-bottom: 1rem;
}
.read-more{
display: flex;
justify-content: flex-end;
}
`]
})
export class UiReadMoreComponent implements AfterViewInit{
@ViewChild('wrapper') wrapper: ElementRef;
isCollapsed: boolean = true;
private contentHeight: string;
private _height: string;
constructor(@Attribute('height') public height: string = '') {
this._height = height;
}
ngAfterViewInit() {
this.contentHeight = this.wrapper.nativeElement.clientHeight + 'px';
}
onIsCollapsed(){
this.isCollapsed = !this.isCollapsed;
this._height = this.isCollapsed ? this.height : this.contentHeight;
}
}
<ui-read-more height="250px">
<ngx-md>
{{post.content}}
</ngx-md>
</ui-read-more>
谢谢你,我改变了它一点它是因为控制台误差对NgOnInit。有它的微小变化,并与6角效果很好。
@Component({
selector: 'app-read-more',
template: `
<div id="textCollapse" [innerHTML]="text" [class.collapsed]="isCollapsed" [style.height]="isCollapsed ? maxHeight+'px' : 'auto'">
</div>
<a *ngIf="isCollapsible" (click)="isCollapsed =! isCollapsed">Read {{isCollapsed ? 'more':'less'}}</a>
`,
styles: [`
div.collapsed {
overflow: hidden;
}
a {
color: #007bff !important;
cursor: pointer;
}
`]
})
export class ReadMoreComponent implements OnInit {
// the text that need to be put in the container
@Input() text: string;
// maximum height of the container
@Input() maxHeight: number;
// set these to false to get the height of the expended container
public isCollapsed = false;
public isCollapsible = false;
constructor(private elementRef: ElementRef) {
}
ngOnInit() {
const currentHeight = document.getElementById('textCollapse').offsetHeight;
if (currentHeight > this.maxHeight) {
this.isCollapsed = true;
this.isCollapsible = true;
}
}
}
正如你可以看到我的改变
const current Height = document.getElementById('textCollapse').offsetHeight;
我又解决了这些类型的问题,动态数据和充分的控制。
<div class="Basic-Info-para">
<p>
<span *ngIf="personalBasicModel.professionalSummary.length>200" id="dots">
{{personalBasicModel.professionalSummary | slice:0:200}} ...
</span>
<span id="more">{{personalBasicModel.professionalSummary }}
</span>
</p>
</div>
在这里,personalBasicModel.professionalSummary包含字符串。像任何文本。 切片:0:200 =使用切片管剪接串200字符长度。你可以根据你的要求改变长度。 ID = “点” &ID = “多” 两个重要的事情。
<div class="Basic-Info-SeeMore">
<button class="SeeMore"(click)="showMore(paasValueOn_SeeMoreBtn)">
{{showLess_More}}
</button>
</div>
在这里我们定义动态文本的按钮(看多和看以下)点击事件。
// ---------------------------------- TS文件------------ ----------------------- //
定义变量
showLess_More:字符串= “查看更多...”; paasValueOn_SeeMoreBtn:布尔= TRUE;
当用户点击看更多的按钮事件(方法)火
showMore(data:boolean){
if(data){
$("#dots").css('display', 'none');
$("#more").css('display', 'inline');
this.showLess_More = "SEE LESS ...";
this.paasValueOn_SeeMoreBtn = false;
}else{
$("#dots").css('display', 'inline');
$("#more").css('display', 'none');
this.showLess_More = "SEE MORE...";
this.paasValueOn_SeeMoreBtn = true;
}
}
您可以使用此插件。
这是非常简单的只用通过它你想用默认[text]
显示[textLength]
和https://www.npmjs.com/package/nga-read-more