当前位置:  开发笔记 > 编程语言 > 正文

Angular 2 Material - 覆盖和门户如何工作?

如何解决《Angular2Material-覆盖和门户如何工作?》经验,为你挑选了0个好方法。

我想创建一个自动完成组件,它向服务器发出请求并在屏幕上呈现接收到的值.我想明白是怎么portaloverlay工作.现在这是我自动完成的组件

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 = new EventEmitter();
    @Output() focus: EventEmitter = new EventEmitter();

    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;
    private onModelChangeSubject: Subject = new Subject();
    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() { }
}

这是HTML



    
        {{field.icon}} 
        {{placeholder}}
        {{field.icon}} 
    
    
        field.icon
    
    
        field.icon
    
    
        {{hint.value}}
    


该组件可以工作,它可以渲染叠加层.覆盖容器呈现选项唯一的问题是宽度.我阅读了门户网站和叠加层的核心概念,但我想了解它如何与角度有效. 这是它现在呈现的方式

谁能解释一下它是如何工作的?或者至少我如何控制它的宽度?

推荐阅读
手机用户2502851955
这个屌丝很懒,什么也没留下!
DevBox开发工具箱 | 专业的在线开发工具网站    京公网安备 11010802040832号  |  京ICP备19059560号-6
Copyright © 1998 - 2020 DevBox.CN. All Rights Reserved devBox.cn 开发工具箱 版权所有