2016-08-22 10 views
12

में चौड़ाई (डीओएम) तत्व की चौड़ाई कैसे प्राप्त करें, वहां कुछ समान थ्रेड हैं लेकिन मुझे अपनी आवश्यकताओं के लिए उपयुक्त उत्तर नहीं मिला। ताकि सीधे डीओएम एक्सेस को से कोणीय 2 में सख्ती से बचाया जाना चाहिए। मैं बस सोच रहा हूं कि इसके लिए सबसे अच्छा अभ्यास क्या है।Angular2

जो मैं प्राप्त नहीं करना चाहता वह वर्तमान चौड़ाई के आधार पर तत्व का आकार बदलना है।

workitemresize.component.ts

import { Directive, ElementRef, HostListener, Renderer, Input } from '@angular/core'; 

@Directive({ 
    selector: '[workItemResize]' 
}) 

export class WorkItemResizeDirective implements ngAfterViewInit { 

    private el: HTMLElement; 
    private renderer: Renderer; 

    constructor(el: ElementRef, public renderer: Renderer) 
    { 
    this.el = el.nativeElement; 
    this.renderer = renderer; 
    } 


    @HostListener('window:resize', ['$event.target']) 
    onResize() 
    { 
    this.resizeWorks(); 
    } 

    ngAfterViewInit() { 
    this.resizeWorks(); 
    } 

    private resizeWorks(): void { 
    this.renderer.setElementStyle(this.el, 'height', this.el.width); // <-- doesn't work I kow that this.el.width doesn't exist but just for demonstration purpose 
    this.renderer.setElementStyle(this.el, 'height', '500'); // <-- works 
    } 

} 

projects.template.html

<div class="posts row"> 
     <div class="work-item col-xs-12 col-sm-6 col-no-padding" workItemResize *ngFor="let post of posts"> 

       <!-- show some fancy image --> 
       <div class="img" [ngStyle]="{'background-image':'url('+post.better_featured_image.source_url+')'}"></div> 

     </div> 
</div> 

संबंधित: https://github.com/angular/angular/issues/6515

+0

अंतहीन लूप की तरह ध्वनि के साथ वर्तमान के आधार पर आकार बदलें। –

+0

इनिट व्यू के बाद और window.resize पर नहीं - यह ठीक होना चाहिए – kkern

उत्तर

10

मैं पाने के लिए एक तरह से पता नहीं हैतक पहुंच के बिना मेजबान तत्व से चौड़ाईलेकिन सेटिंग की तरह किया जा सकता है:

@HostListener('window:resize', ['$event.target']) 
onResize() { 
    this.resizeWorks(); 
} 

@HostBinding('style.height.px') 
elHeight:number; 

private resizeWorks(): void { 
    this.elHeight = this.el.nativeElement.width; 
} 

आप की तरह

<div style="width: 100%;" #div (window:resize)="elHeight = div.getBoundingClientRect()"> 
    <!-- your template here --> 
</div> 

अपने घटक टेम्पलेट के अंदर एक तत्व जोड़ सकते हैं तो यह सब (लेकिन init के बाद नहीं) में प्रत्यक्ष डोम उपयोग के बिना काम करेंगे।

+0

क्या @ होस्ट बाइंडिंग और रेंडरर दृष्टिकोण के बीच कोई उल्लेखनीय अंतर है? मुझे लगता है कि दोनों संस्करण ठीक हैं? ओह और this.el.nativeElement.width हमेशा शून्य है ... इसलिए मैं इसके साथ भी संघर्ष कर रहा था। इसके बारे में: this.renderer.setElementStyle (this.el, 'height', this.el.clientWidth + 'px'); यह काम करता है लेकिन मुझे अजीब लग रहा है ... – kkern

+0

रेंडरर दृष्टिकोण भी ठीक है। मुझे 'होस्ट बाइंडिंग' दृष्टिकोण को पढ़ने में आसान लगता है। आपके प्रश्न में 'this.el.nativeElement.width' की बजाय' this.el.width' है। मुझे लगता है कि घटक को पूरी तरह से प्रस्तुत करने से पहले 'आकार बदलें' वर्क्स को बुलाया जाता है या अन्यथा 'getBoundingClientRect() चौड़ाई' का प्रयास करें। –

+1

el.nativeElement के लिए यह संदर्भ संदर्भ (कन्स्ट्रक्टर देखें)। ठीक है, मैं getBoundingClientRect() चौड़ाई तक चिपक जाता हूं। धन्यवाद! अंतिम कोड लाइन: this.renderer.setElementStyle (this.el, 'height', this.el.getBoundingClientRect() चौड़ाई + "पीएक्स"); – kkern

8

मैंने @ गुंटर ज़ोचबॉयर समाधान की कोशिश की और इसे परिष्कृत किया। Div की सीमा पाने के लिए आपको HostListener की आवश्यकता नहीं है। 'क्लिक' या अन्य ईवेंट (ईवेंट) = "फ़ंक्शन()" की तरह, यह इस फ़ंक्शन को फ़ायर करेगा। मुझे आशा है कि किसी को यह सहायक मिलेगा।

<div #div (window:resize)="onResize(div.getBoundingClientRect())"> 
    <!-- your template here --> 
</div> 


onResize() { 
    this.resizeWorks(); 
} 

@HostBinding('style.height.px') elHeight:number; 

private resizeWorks(): void { 
    this.elHeight = this.el.nativeElement.width; 
} 

(#div) - यह माप लक्ष्य प्राप्त करने के लिए आवश्यक चर है। यह तत्व के समान नाम नहीं होना चाहिए, यह कोई नाम हो सकता है।

तत्व आयाम प्राप्त करने का एक और तरीका कोणीय कोर से एलिमेंटरफ क्लास का उपयोग करना है, लेकिन फिर आपको उस बच्चे तत्व को ढूंढना होगा जिसमें चौड़ाई और ऊंचाई गुण हैं। मैंने कंटेनर चौड़ाई और ऊंचाई प्राप्त करने के लिए एंगुलर 2 मैप्स में इसका इस्तेमाल किया, लेकिन मुझे पता चला कि, इस विधि का उपयोग करके मुझे तत्व वृक्ष तत्व में जाना था जिसमें इन गुण थे और यह रूट तत्व का दूसरा बच्चा था। यह अधिक गन्दा है। एलिमेंट डिमेंशन - केवल एक वर्ग है जिसमें ऊंचाई और चौड़ाई है जिसे मैंने उन गुणों को शामिल किया है।

<div (window:resize)="onResize()"> 
    <!-- your template here --> 
</div> 

private getContainerDimensions(): ElementDimensions{ 
    var rootElement = this.elementRef.nativeElement; 
    var childElement = rootElement.firstElementChild; 
    var contentElement = childElement.firstElementChild; 

    return { 
     height:contentElement.clientHeight, 
     width: contentElement.clientWidth 
    }; 
} 
+0

भी एक अच्छा समाधान! – kkern

0

आप घटक खुद की चौड़ाई अगर है कि एक एक प्रदर्शन संपत्ति (जैसे कि नीचे उदाहरण में 'ब्लॉक' के रूप में) में परिभाषित किया गया है हो सकता है। ध्यान दें कि आप (डोम छाया का प्रयोग करके) इस शैली को परिभाषित करने में सक्षम होना चाहिए:

:host { 
    display:block; 
} 

आप डोम पीछा (आयोनिक 2-3) का उपयोग नहीं कर रहे हैं, तो:

my-component { 
    display:block; 
} 

यहाँ नियंत्रक है (उजागर एक चौड़ाई के रूप में चौड़ाई):

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

@Component({ 
    selector: 'my-component', 
    template: '{{$width|async}}', 
    style: 'my-component {display: block;}' 
}) 
export class MyComponent implements AfterViewInit { 
    @Input() public gridWidth: number; 
    private $width: Subject<number> = new Subject(); 

    constructor(private elementRef: ElementRef) { 
    } 

    public ngAfterViewInit(): void { 
     this.emitWidth(); 
    } 

    @HostListener('window:resize', ['$event.target']) 
    public onResize(): void { 
     this.emitWidth(); 
    } 

    private emitWidth(): void { 
     this.$width.next(this.getWidth()); 
    } 

    private getWidth(): number { 
     return this.getNativeElement().clientWidth; 
    } 

    private getNativeElement(): HTMLElement { 
     return this.elementRef.nativeElement; 
    } 
}