2017-04-14 3 views
1

두 개의 지시문을 만들었습니다. 하나는 모달 팝업에 대한 이벤트를 처리하고 다른 하나는 사용자 지정 도구 팁 이벤트를 처리합니다. 이제는 Modal 지시어에서 도구 팁 지시어로 데이터를 전달하면됩니다. 나는 구글을 시도했지만 유용하지 않았다. 한 지시어에서 다른 지시문으로 값을 전달할 수있는 방법은 정말 있습니까?하나의 지시어에서 다른 지시문으로 데이터를 전달할 수 있습니까?

import { Directive, ElementRef, Input, HostListener, Renderer, ViewChild } from '@angular/core'; 
import { ReportModel } from '../../models/ReportModel'; 
//import {FormFieldModel } from '../../models/FormFieldModel'; 
import { FormFieldModel } from '../../models/FrameworkElementFormFieldModel'; 

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

export class TooltipDirective { 

constructor(public el: ElementRef, public renderer: Renderer) { } 
tooltipTitle: any = ''; 
tooltipText: any = ''; 
tooltipImage: any = ''; 
isFormFieldModel: boolean = false; 
@Input() dataContext: any = new ReportModel(); 
@Input() IsButtonPanel: boolean = false; 



private mouseTop: number = 0; 
private mouseLeft: number = 0; 
tooltipTop: number = 0; 
tooltipLeft: number = 0; 
@HostListener('click') onclick() { 
    this.hover(false); 
} 

@HostListener('mouseenter', ['$event']) onMouseEnter(event: MouseEvent) {debugger 
    this.hover(false); 
    if (this.mainDiv != null) { 
     this.mainDiv.remove(); 
     this.ImgElement.remove(); 
    } 
    this.mouseLeft = event.clientX; 
    this.mouseTop = event.clientY; 
    if (this.dataContext != null) { 

     this.tooltipText = this.dataContext.Description; 

     if (this.dataContext instanceof FormFieldModel) { 
      this.isFormFieldModel = true; 
     } 

     if (this.isFormFieldModel) { 
      if (!this.dataContext.IsShowToolTip) { 
       return; 
      } 
      this.tooltipTitle = this.dataContext.PrettyName; 
     } 
     else { 
      this.tooltipTitle = this.dataContext.Header; 
      this.tooltipImage = this.dataContext.Icon; 
     } 

     if (this.tooltipTitle == '' || this.tooltipTitle == null || this.tooltipTitle == 'null') { 
      this.tooltipTitle = "Header"; 
     } 

     if (this.tooltipText == null || this.tooltipText == 'null') { 
      this.tooltipText = ""; 
     } 

     if (this.tooltipImage == '' || this.tooltipImage == 'null') { 
      this.tooltipImage = "info.png"; 
     } 

     this.hover(true); 
    } 
} 
@HostListener('mouseleave') onMouseLeave() { 
    this.hover(false); 
} 

@HostListener('focusin') onFocus() { 

    if (this.mainDiv != null) { 
     this.mainDiv.remove(); 
     this.ImgElement.remove(); 
    } 

    this.mouseLeft = this.el.nativeElement.getBoundingClientRect().left; 
    this.mouseTop = this.el.nativeElement.getBoundingClientRect().top; 

    if (this.dataContext != null) { 

     this.tooltipText = this.dataContext.Description; 

     if (this.dataContext instanceof FormFieldModel) { 
      this.isFormFieldModel = true; 
     } 

     if (this.isFormFieldModel) { 
      if (!this.dataContext.IsShowToolTip) { 
       return; 
      } 
      this.tooltipTitle = this.dataContext.PrettyName; 
     } 
     else { 
      this.tooltipTitle = this.dataContext.Header; 
      this.tooltipImage = this.dataContext.Icon; 
     } 

     if (this.tooltipTitle == '' || this.tooltipTitle == null || this.tooltipTitle == 'null') { 
      this.tooltipTitle = "Header"; 
     } 

     if (this.tooltipText == null || this.tooltipText == 'null') { 
      this.tooltipText = ""; 
     } 

     if (this.tooltipImage == '' || this.tooltipImage == 'null') { 
      this.tooltipImage = "info.png"; 
     } 

     this.hover(true); 
    } 
} 

@HostListener('focusout') onFocusout(target) { 
    this.hover(false); 
} 

//@HostListener('document:mousemove', ['$event']) 
//onMouseMove(event: MouseEvent) { 
// this.mouseLeft = event.clientX; 
// this.mouseTop = event.clientY; 
//} 

mainDiv: any; ImgElement: any; InputElement: any; divElement: any; divElement1: any; divElement2: any; 
hover(onMouseHover: boolean) {debugger 

    if (onMouseHover && !this.IsButtonPanel) {debugger 
     //Dynamically Create Img Element 

     //Delete existing Tooltip 
     let tooltipItem = this.el.nativeElement.getElementsByClassName("tooltipMain")[0]; 
     if (tooltipItem != null) { 
      tooltipItem.outerHTML = ''; 
     } 
     else 
     { 
      tooltipItem = this.el.nativeElement.nextElementSibling; 
      if (tooltipItem != null && tooltipItem.className.indexOf("tooltipMain") >= 0) 
      { 
       tooltipItem.outerHTML = ''; 
      } 
     } 

     this.ImgElement = this.renderer.createElement(this.el.nativeElement, "img"); 

     this.renderer.setElementAttribute(this.ImgElement, "src", "images/" + this.tooltipImage); 

     //if (this.tooltipImage == '') { 
     // this.renderer.setElementAttribute(this.ImgElement, "src", "images/info.png"); 
     //} 
     //else { 
     // this.renderer.setElementAttribute(this.ImgElement, "src", "images/" + this.tooltipImage); 
     //} 

     this.renderer.setElementStyle(this.ImgElement, "width", "40px"); 
     this.renderer.setElementStyle(this.ImgElement, "height", "40px"); 
     this.renderer.setElementStyle(this.ImgElement, "margin-right", "2px"); 
     this.renderer.setElementStyle(this.ImgElement, "float", "left"); 
     this.renderer.setElementStyle(this.ImgElement, "border", "1px solid #CCC"); 
     this.renderer.setElementStyle(this.ImgElement, "border-radius", "5px"); 
     this.renderer.setElementStyle(this.ImgElement, "padding", "5px"); 
     this.renderer.setElementStyle(this.ImgElement, "backgroundColor", "#f5f5f5"); 

     //tooltip text outer div 

     this.divElement = this.renderer.createElement(this.el.nativeElement, "div"); 

     this.renderer.setElementStyle(this.divElement, "border", "1px solid #CCC"); 
     this.renderer.setElementStyle(this.divElement, "margin-left", "38px !important"); 
     this.renderer.setElementStyle(this.divElement, "color", "black"); 
     this.renderer.setElementStyle(this.divElement, "border-radius", "5px"); 
     this.renderer.setElementStyle(this.divElement, "padding", "5px"); 
     this.renderer.setElementStyle(this.divElement, "float", "left"); 
     this.renderer.setElementStyle(this.divElement, "backgroundColor", "#f5f5f5"); 
     this.renderer.setElementStyle(this.divElement, "text-align", "left !important"); 

     //tooltip text header div 

     this.divElement1 = this.renderer.createElement(this.el.nativeElement, "div"); 

     this.renderer.setElementClass(this.divElement1, "header", true); 
     this.renderer.createText(this.divElement1, this.tooltipTitle); 


     //tooltip text description div 

     this.divElement2 = this.renderer.createElement(this.el.nativeElement, "div"); 

     this.renderer.setElementClass(this.divElement2, "description", true); 
     this.renderer.createText(this.divElement2, this.tooltipText); 


     this.mainDiv = this.renderer.createElement(this.el.nativeElement, "div"); 

     this.renderer.setElementProperty(this.mainDiv, "disabled", true); 
     this.renderer.setElementClass(this.mainDiv, "tooltipMain", true); 


     let tooltipWidth = this.mainDiv.clientWidth + 10; 
     let tooltipHeight = this.mainDiv.clientHeight + 10; 

     let windowWidth = window.innerWidth; 
     let windowHeight = window.innerHeight; 

     if ((windowWidth - this.mouseLeft) < tooltipWidth) { 
      //this.tooltipLeft = windowWidth - (tooltipWidth); 
      this.renderer.setElementStyle(this.mainDiv, "right", "0px"); 
     } else { 
      //this.tooltipLeft = this.mouseLeft; 
      this.renderer.setElementStyle(this.mainDiv, "left", this.mouseLeft + "px"); 
     } 

     if ((windowHeight - this.mouseTop) < tooltipHeight) { 
      this.tooltipTop = this.mouseTop - 20; 
      this.renderer.setElementStyle(this.mainDiv, "bottom", "0px"); 
     } else { 
      this.renderer.setElementStyle(this.mainDiv, "top", this.mouseTop + 5 + "px"); 
     } 

     this.mainDiv.appendChild(this.ImgElement); 
     this.divElement.appendChild(this.divElement1); 
     this.divElement.appendChild(this.divElement2); 
     this.mainDiv.appendChild(this.divElement); 
     //this.renderer.setElementStyle(this.mainDiv, "left", this.tooltipLeft + "px"); 
     //this.renderer.setElementStyle(this.mainDiv, "top", this.tooltipTop + "px"); 
    } 
    else { 
     if (this.mainDiv != null) { 
      this.mainDiv.remove(); 
      this.ImgElement.remove(); 
     } 
    } 
} 
} 

그리고 다음과 같이 내 팝업 드래그 가능한 지침은 다음과 같습니다 : 다음과 같이

툴팁 지침은

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

@Directive({ 
    selector: '[draggable-component]' 
}) 
export class DraggableDirective implements OnInit { 
topStart: number = 0; 
leftStart: number = 0; 
_allowDrag: boolean = true; 
valueTop: any = 0; 
valueLeft: any = 0; 
md: boolean; 

constructor(public element: ElementRef) { } 

ngOnInit() { 
    if (this._allowDrag) { 
     this.element.nativeElement.style.position = 'absolute'; 
    } 
} 

@HostListener('mousedown', ['$event']) 
onMouseDown(event: MouseEvent) { 
    if (event.button === 2) 
     return; // prevents right click drag, remove his if you don't want it 
    this.md = true; 
    this.topStart = event.clientY - this.element.nativeElement.style.top.replace('px', ''); 
    this.leftStart = event.clientX - this.element.nativeElement.style.left.replace('px', ''); 
} 

@HostListener('document:mouseup') 
onMouseUp(event: MouseEvent) { 
    this.md = false; 
} 

@HostListener('document:mousemove', ['$event']) 
onMouseMove(event: MouseEvent) { 
    if (this.md && this._allowDrag) { 

     this.valueTop = this.element.nativeElement.style.top = (event.clientY - this.topStart) + 'px'; 
     console.log(this.valueTop); 
     this.valueLeft = this.element.nativeElement.style.left = (event.clientX - this.leftStart) + 'px'; 
     console.log(this.valueLeft); 
    } 
} 

@HostListener('touchstart', ['$event']) 
onTouchStart(event: TouchEvent) { 
    this.md = true; 
    this.topStart = event.changedTouches[0].clientY - this.element.nativeElement.style.top.replace('px', ''); 
    this.leftStart = event.changedTouches[0].clientX - this.element.nativeElement.style.left.replace('px', ''); 
    event.stopPropagation(); 
} 

@HostListener('document:touchend') 
onTouchEnd() { 
    this.md = false; 
} 

@HostListener('document:touchmove', ['$event']) 
onTouchMove(event: TouchEvent) { 
    if (this.md && this._allowDrag) { 
     this.element.nativeElement.style.top = (event.changedTouches[0].clientY - this.topStart) + 'px'; 
     this.element.nativeElement.style.left = (event.changedTouches[0].clientX - this.leftStart) + 'px'; 
    } 
    event.stopPropagation(); 
} 
} 

지금 내가 툴팁에 드래그 가능한 지침에서 valueTopvalueLeft을 통과해야합니다. 그리고 이것이 내가 원하는 것입니다.

@Injectable() 
export class Myservice{ 
    private _foo=new BehaviorSubject<string>("foo"); 
    setFoo(foo:string){ 
    this._foo.next(foo); 
    } 
    foo = this._foo.asObservable() 
} 
@Directive({ 
    selector: '[draggable-component]' 
}) 
export class DraggableDirective{ 
    constructor(public element: ElementRef, private service: MyService) { 
    this.service.setFoo("bar"); 
    } 
} 
@Directive( 
{ 
    selector: '[Tooltip]' 
}) 
export class TooltipDirective { 

    constructor(public el: ElementRef, public renderer: Renderer, private service:MyService) {} 

    ngOnInit(){ 
    this.service.foo.subscribe(value=>console.log(value)); 
    } 

} 

:

+0

일부 코드를 게시하십시오. 지침에 추가 된 요소는 무엇입니까? –

+0

@ GünterZöchbauer 안녕하세요. 내 지시어로 모델 및 마우스를 드래그하고 입력하고 이동하는 것과 같은 이벤트를 찾고 있습니다. 그래서 저는 한 지시어에서 다른 지시어로 값을 전달하기를 원합니다. 나는 그것이 가능한지 아닌지를 알고 싶다. 그리고 가능한 경우 어떻게. 나는 단지 데모를 찾고있다. –

+0

지시어의 위치에 따라 방법이 다를 수 있으므로 일부 코드를 보여주십시오. –

답변

2

당신의 지시는 관련이없는 것처럼, 당신은 모두 당신의 지시에 주입하는 서비스를 만들어야합니다, 해당 서비스는 그들 사이의 통신 채널이 될 것입니다 BehaviorSubject을 사용합니다. 다른 하나가 구독하기 전에 값을내는 DraggableDirective에 직면 할 수 있으므로 적절한 시간에 올바른 값을 얻지 못할 수 있습니다. 그러나 당신은 구현을 위해 완전히 자유 롭다. 필요에 더 잘 맞을 것이라고 생각한다면 Observable/Subject을 기반으로하지 않는 패턴을 사용할 수도있다.

+0

이 서비스를 사용할 필요가없는 다른 방법이 있습니까? –

+1

지시어와 관련이없는 경우 그 방법 밖에 없습니다. 만약 부모/자식이라면'@Input()'과'@Output()'을 사용하거나 "transclusion"이 있다면 자식을 부모에게 주입 할 수 있습니다 : ' – n00dl3