我拼命地尝试从我写的课上开始一个事件。我在我的YUI Widget中使用这个类,我想让我的YUI小部件响应被触发的事件。 我知道Bubbling事件是如何工作的,所以这里的代码工作得非常好:
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();});
然而,当我尝试将这个概念应用到我的Widget时,我非常努力地失败。
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"]});
Chromium中的日志输出是:
似乎我真的很想念Widgets的必备内容。请帮助我,以便更好地理解这个主题。
答案 0 :(得分:1)
我认为答案在Mitch的帖子中。您需要在泡泡目标订阅上为事件添加前缀。所以而不是:
this.on("testEvent", function () {
Y.log("This should, but won't appear despite how hard I try!");
});
尝试:
this.on("*:testEvent", function () {
Y.log("This should, but won't appear despite how hard I try!");
});
或者在你的Slide类上设置.NAME(你应该这样做):
Slide.NAME = "Slide";
然后你的前缀使用该值:
this.on("Slide:testEvent", function () {
Y.log("This should, but won't appear despite how hard I try!");
});
使用Y.Base.create会删除大量样板文件。
答案 1 :(得分:0)
我无法告诉你为什么它在普通的JS-Object和Y.Widget必须交互时失败,而它与两个普通的JS-Objects一起工作。
然而,延长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");
}
});
这里重要的是NAME-Attribute - 它将成为您的小部件监听的前缀:
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中,您将调用:
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.
}
答案 2 :(得分:0)
有趣的问题!
所以我试图深入解决这个问题。
首先,我已经测试了@Mitch的例子 - 正如预期的那样有效!证明:http://jsfiddle.net/pqr7/hQBHH/3/
但是如果Slide是普通对象(不是从Y.Base扩展)怎么办?我已经从@ brian-j-miller测试了一些例子并且它不起作用。证明:http://jsfiddle.net/pqr7/hQBHH/4/
然后我运行我的萤火虫并逐步进入YUI源。现在我知道它的细节如何运作了!
让我们看看普通对象Slide http://jsfiddle.net/pqr7/hQBHH/4/的示例
当我在普通对象Slide上执行this.fire("testEvent");
时,YUI在内部调用链中的许多函数,并使用事件type
进行操作,即字符串= "testEvent"
(我将其称为“类型”,因为在源代码中代码它总是保存在名为“type”的变量上。
我发现事件气泡和丰富的目标(SlideShow的实例)如预期的那样。
然后它检查SlideShow是否有一些订阅者用于type
== "testEvent"
的活动?答:不!
如果您在SlideShow中订阅this.on('testEvent', ...)
,则其实际存储为字符串type
== "SlideShow:testEvent"
如果您在SlideShow中订阅this.on('*:testEvent', ...)
,则其实际存储为字符串type
== "*:testEvent"
如果您在SlideShow中订阅this.on('Slide:testEvent', ...)
,则其实际存储为字符串type
== "Slide:testEvent"
但冒泡的是:简单type
== "testEvent"
,因此SlideShow实例中没有订阅者。
然后,YUI用*:testEvent
检查更复杂的规则。不幸的是,我们的简单字符串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时,这就是区别 - firered事件不是一个简单的testEvent
而是Slide:testEvent
,它会模式化*:testEvent
(http:// jsfiddle达网络/ pqr7 / hQBHH / 3 /)