2017-01-19 12 views
8

मैं एक स्वत: पूर्ण घटक बनाना चाहता हूं जो सर्वर को अनुरोध करता है और स्क्रीन पर प्राप्त मान प्रस्तुत करता है। मैं समझने की कोशिश कर रहा हूं कि portal और overlay काम कैसे करें। अभी यह स्वत: पूर्णकोणीय 2 सामग्री - ओवरले और पोर्टल कैसे काम करते हैं?

import { 
    Component, OnInit, Input, Output, EventEmitter, OnDestroy, ViewChild, ViewContainerRef, 
    ElementRef, Optional 
} from '@angular/core'; 
import { ControlValueAccessor } from '@angular/forms'; 
import { MdOption, ConnectedOverlayDirective, Dir, transformPlaceholder, transformPanel, fadeInContent } from '@angular/material'; 

import { Subscription } from 'rxjs/Subscription'; 
import { BehaviorSubject } from 'rxjs/BehaviorSubject'; 
import { Subject } from 'rxjs/Subject'; 

import { AutocompleteConfiguration } from './autocomplete-config.model'; 
import { SearchState, SearchingService, IBackend } from './../../services/searching.service'; 
import { ISearchConfig } from './../../models/iSearch-config'; 
import { IHint } from './../generic-form/generic-form.service'; 
import { getValueAccessorProviders } from './../../models/custom-value-accessor.builder'; 

@Component({ 
    selector: 'autocomplete', 
    templateUrl: './autocomplete.html', 

    providers: [ 
     SearchingService, 
     getValueAccessorProviders(AutocompleteComponent) 
    ], 
    animations: [ 
     transformPlaceholder, transformPanel, fadeInContent 
    ] 
}) 
export class AutocompleteComponent implements OnInit, OnDestroy, ControlValueAccessor { 
    /** Placeholder to be shown if no value has been selected. */ 
    @Input() 
    get placeholder() { return this._placeholder; } 
    set placeholder(value: string) { 
     this._placeholder = value; 

     // Must wait to record the trigger width to ensure placeholder width is included. 
     Promise.resolve(null).then(() => this._triggerWidth = this._getWidth()); 
    } 
    @Input() hint: IHint = null; 
    @Input() iconPosition: string = ''; // 'prefix', 'suffix' or 'placeholder-prefix', 'placeholder-suffix' 
    @Input() autocompleteConfigurtation: AutocompleteConfiguration; 
    @Input() backend: IBackend; 
    @ViewChild(ConnectedOverlayDirective) overlayDir: ConnectedOverlayDirective; 
    /** Trigger that opens the select. */ 
    @ViewChild('triggerRef', { read: ElementRef }) trigger: ElementRef; 

    @Output() blur: EventEmitter<FocusEvent> = new EventEmitter<FocusEvent>(); 
    @Output() focus: EventEmitter<FocusEvent> = new EventEmitter<FocusEvent>(); 

    get value() { 
     return this._inputValue; 
    } 
    set value(value: any) { 
     if (String(value) !== String(this._inputValue)) { 
      this._inputValue = String(value); 
     } 
    } 

    /** Whether or not the overlay panel is open. */ 
    private _panelOpen = false; 
    /** The currently selected option. */ 
    private _selected: MdOption; 
    private _placeholder: string; 
    /** 
    * The width of the trigger. Must be saved to set the min width of the overlay panel 
    * and the width of the selected value. 
    */ 
    private _triggerWidth: number; 

    private _inputValue: string = ''; 
    private _focused: boolean = false; 
    private _disabled: boolean = false; 

    private onSearchStateChange: BehaviorSubject<SearchState>; 
    private onModelChangeSubject: Subject<any> = new Subject<any>(); 
    private subscriptions: Subscription[] = []; 

    private searchState: SearchState = null; 

    /** 
    * The x-offset of the overlay panel in relation to the trigger's top start corner. 
    * This must be adjusted to align the selected option text over the trigger text when 
    * the panel opens. Will change based on LTR or RTL text direction. 
    */ 
    _offsetX = 0; 

    /** 
    * The y-offset of the overlay panel in relation to the trigger's top start corner. 
    * This must be adjusted to align the selected option text over the trigger text. 
    * when the panel opens. Will change based on the y-position of the selected option. 
    */ 
    _offsetY = 0; 

    /** The value of the select panel's transform-origin property. */ 
    _transformOrigin: string = 'top'; 

    /** The animation state of the placeholder. */ 
    _placeholderState = ''; 

    /** 
    * This position config ensures that the top "start" corner of the overlay 
    * is aligned with with the top "start" of the origin by default (overlapping 
    * the trigger completely). If the panel cannot fit below the trigger, it 
    * will fall back to a position above the trigger. 
    */ 
    _positions = [ 
     { 
      originX: 'start', 
      originY: 'top', 
      overlayX: 'start', 
      overlayY: 'top', 
     }, 
     { 
      originX: 'start', 
      originY: 'bottom', 
      overlayX: 'start', 
      overlayY: 'bottom', 
     }, 
    ]; 
    /** The scroll position of the overlay panel, calculated to center the selected option. */ 
    private _scrollTop = 0; 
    constructor(
     private searchBuilder: SearchingService, 
     @Optional() private _dir: Dir 
    ) { } 

    ngOnInit() { 
     this.onSearchStateChange = this.searchBuilder 
      .createSearchObservable(this.onModelChangeSubject, this.autocompleteConfigurtation.searchConfig, this.backend); 
     this.setSearchStateChangeSubscription(); 
    } 

    setSearchStateChangeSubscription() { 
     this.subscriptions.push(
      this.onSearchStateChange.subscribe(newState => { 
       debugger 
       this.searchState = newState; 
       // this._calculateOverlayPosition(); 
       this._placeholderState = this._isRtl() ? 'floating-rtl' : 'floating-ltr'; 
       this._panelOpen = newState && newState.responseObject && newState.responseObject.length > 0; 
      }) 
     ); 
    } 

    onModelChange(inputValue) { 
     this.value = inputValue; 
     this._onChangeCallback(this._inputValue); 
     this._onTouchedCallback(); 
     this._activateSearch(this.value); 
    } 

    // From ControlValueAccessor interface 
    // the ngModel init or form write value 
    writeValue(value: any) { 
     this.value = value; 
    } 

    // From ControlValueAccessor interface 
    registerOnChange(fn: any) { 
     this._onChangeCallback = fn; 
    } 

    // From ControlValueAccessor interface 
    registerOnTouched(fn: any) { 
     this._onTouchedCallback = fn; 
    } 

    setDisabledState(isDisabled: boolean) { 
     this._disabled = isDisabled; 
    } 

    close() { 

    } 

    ngOnDestroy() { 
     this.subscriptions.forEach(val => val.unsubscribe()); 
     this.subscriptions = []; 
     this.onModelChangeSubject.unsubscribe(); 
    } 

    /** 
    * Sets the scroll position of the scroll container. This must be called after 
    * the overlay pane is attached or the scroll container element will not yet be 
    * present in the DOM. 
    */ 
    _setScrollTop(): void { 
     const scrollContainer = 
      this.overlayDir.overlayRef.overlayElement.querySelector('.md-select-panel'); 
     scrollContainer.scrollTop = this._scrollTop; 
    } 
    /** The width of the trigger element. This is necessary to match 
     * the overlay width to the trigger width. 
     */ 
    _getWidth(): number { 
     return this._getTriggerRect().width; 
    } 

    _isRtl(): boolean { 
     return this._dir ? this._dir.value === 'rtl' : false; 
    } 

    _onPanelDone($event) { 
     console.log($event); 
    } 

    private _getTriggerRect(): ClientRect { 
     return this.trigger.nativeElement.getBoundingClientRect(); 
    } 

    private _activateSearch(value) { 
     if (this._disabled || !this.focus) { 
      return; 
     } 

     this.onModelChangeSubject.next(value); 
    } 

    private _handleFocus($event) { 
     this._focused = true; 

     if (this.autocompleteConfigurtation.activateOnFocus) { 
      this._activateSearch(this.value); 
     } 
     this.focus.emit($event); 
    } 

    private _handleBlur($event) { 
     this._focused = false; 
     this._onTouchedCallback(); 
     this.blur.emit($event); 
    } 

    private _onChangeCallback(_: any) { } 
    private _onTouchedCallback() { } 
} 

के लिए मेरे घटक है और यह एचटीएमएल

<md-input type="text" 
    #triggerRef 
    #origin="cdkOverlayOrigin" 
    cdk-overlay-origin 
    [disabled]="_disabled" 
    [(ngModel)]="value" 
    (blur)="_handleBlur($event)"  
    (focus)="_handleFocus($event)" 
    (ngModelChange)="onModelChange($event)"> 

    <md-placeholder *ngIf="placeholder || iconPosition.indexOf('placeholder') !== -1"> 
     <i *ngIf="iconPosition === 'placeholder-prefix'" class="material-icons app-input-icon">{{field.icon}}</i> 
     {{placeholder}} 
     <i *ngIf="iconPosition === 'placeholder-suffix'" class="material-icons app-input-icon">{{field.icon}}</i> 
    </md-placeholder> 
    <span md-prefix> 
     <md-icon *ngIf="iconPosition === 'prefix'">field.icon</md-icon> 
    </span> 
    <span md-suffix> 
     <md-icon *ngIf="iconPosition === 'suffix'">field.icon</md-icon> 
    </span> 
    <md-hint *ngIf="hint" [align]="hint.align"> 
     {{hint.value}} 
    </md-hint> 
</md-input> 
<template 
    cdk-connected-overlay 
    hasBackdrop 
    backdropClass="cdk-overlay-transparent-backdrop" 
    [origin]="origin" 
    [open]="_panelOpen" 
    [positions]="_positions" 
    [minWidth]="_triggerWidth" 
    [offsetY]="_offsetY" 
    [offsetX]="_offsetX" 
    (backdropClick)="close()" 
    (attach)="_setScrollTop()"> 
    <div class="md-select-panel" 
     [@transformPanel]="'showing'" 
     [style.transformOrigin]="_transformOrigin" 
     [class.md-select-panel-done-animating]="_panelDoneAnimating" 
     (@transformPanel.done)="_onPanelDone()" 
     (keydown)="log($event)"> 
     <div class="md-select-content" [@fadeInContent]="'showing'"> 
      <md-option *ngFor="let option of searchState?.responseObject" 
         [value]="option.value"> 
         {{ option?.text }} 
      </md-option> 
     </div> 
    </div> 
</template> 

घटक काम करता है और यह एकदम सही ढंग से ओवरले बना देता है। ओवरले कंटेनर विकल्पों को प्रस्तुत करता है केवल समस्या चौड़ाई है। मैंने पोर्टलों और ओवरले की मूल अवधारणाओं को पढ़ा लेकिन मैं समझना चाहता हूं कि यह वास्तव में कोणीय के साथ कैसे काम करता है। Here is how it renders right now

क्या कोई यह बता सकता है कि यह कैसे काम करता है? या कम से कम मैं इसकी चौड़ाई कैसे नियंत्रित करता हूं?

उत्तर

0

मैं अगर किसी को भी एक उदाहरण आप एक नज़र here मैं के बारे में मैं यह काम करता है कैसे लगता टिप्पणी जोड़ने की कोशिश करेंगे के लिए कोशिश कर सकते हैं चाहता है ओवरले घटक का उपयोग करने में कामयाब रहे। इसके बारे में कुछ दस्तावेज और इसका उपयोग कैसे करें और अधिक @ कोणीय/सामग्री से स्वागत किया जाएगा। मुझे लगता है कि जो गुंबद पेड़ में प्रदान करने की आवश्यकता तीसरे पक्ष के घटकों अतिप्रवाह के साथ समस्याओं छिपा है या translate3d

CDK प्रलेखन cdk docs भी here जारी किया गया था नहीं करने के लिए बनाने के लिए बहुत उपयोगी है एक उपयोगी गाइड है ओवरले के लिए।

संबंधित मुद्दे