2012-08-26 4 views
1

나는 내가 쓴 수업에서 필사적으로 사건을 일으키려고 노력한다. YUI 위젯 내에서이 클래스를 사용하고 YUI 위젯이 해고 된 이벤트에 응답하기를 원합니다. 나는 이벤트 버블 링이 작동, 그래서 여기에이 코드는 절대적으로 잘 작동 방법을 알고 :위젯 내부의 클래스에서 버블 링 이벤트가 발생 했습니까?

YUI().use('event-custom', 'node', function (Y) { 

function Publisher(bubbleTo) { 
     this.addTarget(bubbleTo); 
     this.publish("testEvent", { 
      emitFacade: true 
     }); 
     this.fire("testEvent"); 
} 

function BubbleTarget() { 

    this.on("testEvent", function (e) {Y.log("Bubbling in Test.js succeed!")}); 
    var newPublisher = new Publisher(this); 
} 
// To fire events or be a bubble target, augment a class with EventTarget 
Y.augment(Publisher, Y.EventTarget); 
Y.augment(BubbleTarget, Y.EventTarget); 

var bubbleTarget = new BubbleTarget();}); 

그러나, 나는 아주 열심히 실패 내 위젯에이 개념을 적용하려고한다.

YUI.add("SlideShow", function(Y) { 

function SlideShow(config) { 
    SlideShow.superclass.constructor.apply(this, arguments); 
} 

SlideShow.NAME = "SlideShow"; 

Y.extend(SlideShow, Y.Widget, { 
    initializer: function() { 
     Y.log("Widget loaded!"); 
     this.on("testEvent", function() { 
       Y.log("This should, but won't appear despite how hard I try!"); 
      }); 
    }, 

    renderUI: function(){ 
     var testSlide = new Slide("text", this); 
    } 
}); 

Y.SlideShow = SlideShow; 

function Slide(sendTo) 
{ 
this.addTarget(sendTo); 
    this.publish("testEvent", { 
     defaultFn: function(){Y.log('Event published.')}, 
     emitFacade: true 
    }); 
    this.fire("testEvent"); 
} 

Y.augment(Slide,Y.EventTarget, true, null, {emitFacade: true}); 
}, "0.0.1", {requires:["widget","event-custom","node","anim"]}); 

크롬에서 로그 출력은 다음과 같습니다 Test.js에서

  • 버블 성공!
  • 위젯로드!
  • 이벤트가 게시되었습니다.

위젯에 대해 뭔가 중요한 것을 놓친 것처럼 보입니다. 이 주제를 더 잘 이해하기 위해 나를 도와주세요.

답변

0

평범한 JS 개체와 Y.Widget이 상호 작용해야 할 때 왜 실패하는지 말할 수는 없지만 두 개의 일반 JS 개체로 작동합니다.

그러나 Y.Base의 힘으로 당신에게 이점을 제공하면서, 문제가 해결됩니다 Y.Base을 연장 :

function Slide(config) 
{ 
    Slide.superclass.constructor.apply(this, config); 
} 

Slide.NAME = "slide"; 

Y.extend(Slide, Y.Base, { 

    initializer : function() { 
       this.publish("testEvent", { 
        emitFacade: true//you do not need to specify this, 
            //it will be set implicitly to true 
            //when using Y.Base 
       }); 
      }, 
    test : function(arg) { 
     this.addTarget(arg); 
     this.fire("testEvent"); 
    } 
}); 

여기서 중요한 점은 이름 특성은 - 그것은 접두사가 될 것이다

이 renderUI에서
Y.extend(SlideShow, Y.Widget, { 
    initializer: function() { 
     Y.log("Widget loaded!"); 
     this.on("slide:testEvent", function() { 
      Y.log("This will work!"); 
     }); 

     this.on("*:testEvent", function() { 
      Y.log("This will work, too no matter what's the Event's prefix!"); 
     }); 

     this.on("Slide:testEvent", function() { 
       Y.log("This won't work, since the prefix doesn't match the NAME-Attribute!"); 
     }); 
    }, 
    //rendering etc. 
}); 

당신이 전화 할게 : 대한 위젯은 듣는

renderUI: function(){ 
    var testSlide = new Slide(); 
    testSlide.on('testEvent', function(e) { 
     Y.log('You can listen for testEvent without a prefix on a Slide-object.'); 
    }); 
    testSlide.test(this);//adds this Widget as the target for the testSlide. 
} 
+0

그래서 다른 위젯을 만들 것입니다. :/음, 내가 처리해야 겠어. – McWhite

1

대답은 내가 생각하는 미치의 게시물에 있습니다. 버블 대상 구독에 이벤트 앞에 접두사를 추가해야합니다. 그래서 대신 :

this.on("testEvent", function() { 
    Y.log("This should, but won't appear despite how hard I try!"); 
}); 

시도 :

Slide.NAME = "Slide"; 

을 다음 접두사는 그 값을 사용하여 슬라이드 클래스 .NAME 설정

this.on("*:testEvent", function() { 
    Y.log("This should, but won't appear despite how hard I try!"); 
}); 

또는 (당신은 어쨌든해야한다) :

this.on("Slide:testEvent", function() { 
    Y.log("This should, but won't appear despite how hard I try!"); 
}); 

Y.Base.create will 많은 양의 상용구를 잘라 낸다.

0

흥미로운 질문입니다!

그래서 저는 deepper로 가서 문제를 분리하려고했습니다.

먼저 @Mitch의 예제를 테스트했습니다. 예상대로 작동합니다! 증명 : http://jsfiddle.net/pqr7/hQBHH/3/

그러나 슬라이드가 일반 개체 (Y.Base에서 확장되지 않음) 인 경우 어떻게해야합니까? @ brian-j-miller의 예제를 테스트했지만 작동하지 않습니다.증거 : http://jsfiddle.net/pqr7/hQBHH/4/

그런 다음 나는 방화복을 풀고 유이 소스를 단계별로 다이빙합니다. 그리고 이제는 그것이 어떻게 작동 하는지를 자세히 알고 있습니다!

것은 우리가 나는 일반 객체 슬라이드에 this.fire("testEvent");을 수행 할 때 http://jsfiddle.net/pqr7/hQBHH/4/ 가, 유이는 내부적으로 체인에 많은 기능을 호출하고 문자열 인 이벤트 type으로 작동 일반 객체 슬라이드와 예제를 보자 = "testEvent"는 (I는 "유형"를 호출 소스 코드에서 항상 "type"이라는 이름의 변수에 저장되기 때문에). 그 이벤트 거품과 풍부한 표적 (슬라이드 쇼의 인스턴스) 예상대로 발견. 그런 다음 SlideShow에 type == "testEvent" 인 이벤트에 대한 구독자가 있는지 확인합니다. 답변 : 안돼!

당신은 this.on('testEvent', ...)로 슬라이드 쇼에서 가입을 한 경우는 당신이 this.on('*:testEvent', ...)으로 슬라이드 쇼에서 가입을하면 실제로 문자열 type == "SlideShow:testEvent"

로 저장은 실제로 문자열 type ==로 저장 "*:testEvent"

당신이 만약 SlideShow에서 서브 스크립 션을 만들려면 문자열로 실제로 저장하십시오. type == "Slide:testEvent"

하지만 버블 링되는 것은 간단합니다. type == "testEvent", SlideShow 인스턴스 안에 구독자가 없습니다.

그런 다음 YUI는 *:testEvent으로 더 복잡한 규칙을 검사합니다. Unfortunatelly 우리의 간단한 문자열 testEvent*:testEvent 다음 가 원래의 코드 패턴과 일치하지 않는 http://yuilibrary.com/yui/docs/api/files/event-custom_js_event-target.js.html#693

여기

if (type.indexOf(PREFIX_DELIMITER) > -1) { /* make a magic to execute a subscriber */ }

type 우리의 버블 문자열 testEvent이며이 PREFIX_DELIMITER 포함하지 않는입니다 (콜론)

그리고 이것은 Y.Base에서 Slide를 연장 할 때의 차이입니다 - 화재 이벤트는 testEvent이지만 Slide:testEvent이 아니라 간단한 패턴 *:testEvent (http://jsfiddle.net/pqr7/hQBHH/)이됩니다. 3 /)