Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/414.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript 在余烬中传播悬停事件_Javascript_Ember.js - Fatal编程技术网

Javascript 在余烬中传播悬停事件

Javascript 在余烬中传播悬停事件,javascript,ember.js,Javascript,Ember.js,我有一个列表,我想检测用户何时将鼠标悬停在其中的li上。问题是mouseEnter似乎并没有传播。目前,我正在使用以下方法: // components/hover-pad.js export default Ember.Component.extend({ template: Em.Handlebars.compile('{{yield}}'), mouseEnter: function(){ this.sendAction("action"

我有一个列表,我想检测用户何时将鼠标悬停在其中的li上。问题是mouseEnter似乎并没有传播。目前,我正在使用以下方法:

// components/hover-pad.js
export default Ember.Component.extend({
    template: Em.Handlebars.compile('{{yield}}'),

    mouseEnter: function(){
        this.sendAction("action", this.get("ctx"));
    },

    action: function(){
        return "hover";
    }.property()
});

// components/project-picker.js
export default Ember.Component.extend({
    actions: {
        hover: function(ctx){
            console.log("caught propagated hover");
        }
    }
})

// templates/components/project-picker/hbs
<ul>
    {{#each project in projects}}
    <li>{{#hover-pad ctx="project"}}</li>
    {{/each}}
</ul>
//组件/hover-pad.js
导出默认的Ember.Component.extend({
模板:Em.handlebar.compile({yield}}'),
mouseEnter:function(){
this.sendAction(“action”,this.get(“ctx”);
},
行动:功能(){
返回“悬停”;
}.property()
});
//组件/project-picker.js
导出默认的Ember.Component.extend({
行动:{
悬停:功能(ctx){
log(“捕获传播的悬停”);
}
}
})
//模板/组件/项目选择器/hbs
    {{{#项目中的每个项目}
  • {{{#hover pad ctx=“project”}
  • {{/每个}}
这是可行的,但我真的觉得我错过了一些余烬启示,一个更地道的梅会怎么做呢

更新 我还应该提到,除了悬停事件之外,我还想捕获点击,这意味着不可能使用动作助手

{{#view App.ClickHoverView contextBinding=item}}
   {{item}}
{{/view}}

App.ClickHoverView = Em.View.extend({
  tagName:'li',
  click:function(){
     this.get('controller').send('click', this.get('context'));
  },
  mouseEnter:function(){
     this.get('controller').send('hover', this.get('context'));
  }
});


啊,您可以在应用程序中注册自定义事件。我所要做的就是加上:

var App = Ember.Application.extend({
  customEvents: {
    "mouseover": "mouseOver"
  }
});
由于鼠标悬停向上传播视图,我可以在父视图中处理它:

// components/project-picker.js
export default Ember.Component.extend({
    mouseOver: function(ctx){
        console.log("caught propagated hover");
    }
})

啊,你可以在应用程序中注册自定义事件。我所要做的就是加上:

var App = Ember.Application.extend({
  customEvents: {
    "mouseover": "mouseOver"
  }
});
由于鼠标悬停向上传播视图,我可以在父视图中处理它:

// components/project-picker.js
export default Ember.Component.extend({
    mouseOver: function(ctx){
        console.log("caught propagated hover");
    }
})

好的,现在尝试另一种方法,这次我创建了一个自定义组件,用于列表中的每个项目

export default Ember.Component.extend({
    tagName: "a",
    template: Ember.Handlebars.compile('{{project.name}}'),

    click: function(){
        this.sendAction('projectClicked', this.get("project"));
    },

    mouseOver: function(){
        this.sendAction('projectHovered', this.get("project"));
    },

    projectClicked: function(){
        return "projectClicked";
    }.property(),

    projectHovered: function(){
        return "projectHovered";
    }.property()
});
然后在主组件中,我为已发送的操作注册处理程序:

// components/project-picker.js
export default Ember.Component.extend({
    actions: {
        projectClicked: function(project){
            console.log("caught propagated hover");
        },
        projectHovered: function(project){
            console.log("caught propagated hover");
        } 
    }
})

这是可行的,但这里仍然感觉有点粗糙,特别是sendAction方法(通过调用另一个属性)上的间接寻址似乎非常冗长。为什么不直接将操作的名称传递给sendAction?看起来我最终会创建大量的组件来分派事件。也许可以创建一个通用链接,截取所有事件并将它们与上下文一起发送…

好的,现在尝试另一种方法,这次我创建了一个自定义组件,用于列表中的每个项目

export default Ember.Component.extend({
    tagName: "a",
    template: Ember.Handlebars.compile('{{project.name}}'),

    click: function(){
        this.sendAction('projectClicked', this.get("project"));
    },

    mouseOver: function(){
        this.sendAction('projectHovered', this.get("project"));
    },

    projectClicked: function(){
        return "projectClicked";
    }.property(),

    projectHovered: function(){
        return "projectHovered";
    }.property()
});
然后在主组件中,我为已发送的操作注册处理程序:

// components/project-picker.js
export default Ember.Component.extend({
    actions: {
        projectClicked: function(project){
            console.log("caught propagated hover");
        },
        projectHovered: function(project){
            console.log("caught propagated hover");
        } 
    }
})

这是可行的,但这里仍然感觉有点粗糙,特别是sendAction方法(通过调用另一个属性)上的间接寻址似乎非常冗长。为什么不直接将操作的名称传递给sendAction?看起来我最终会创建大量的组件来分派事件。也许可以创建一个通用链接,截取所有事件并将它们与上下文一起发送…

好的,这是一个更通用的解决方案,用于在父视图中触发操作并在上下文中传递

// components/evented-tag.js
export default Ember.Component.extend(
    function(){
        var definition = {
            template: Ember.Handlebars.compile('{{yield}}'),
        };

        var events = Ember.A(["touchStart", "touchMove", "touchEnd", "touchCancel", "keyDown", "keyUp", "keyPress", "mouseDown", "mouseUp", "contextMenu", "click", "doubleClick", "mouseMove", "focusIn", "focusOut", "mouseEnter", "mouseLeave", "submit", "change", "dragStart", "drag", "dragEnter", "dragLeave", "dragOver", "drop", "dragEnd"]);

        var self = this;
        events.forEach(function(event){
            definition[event] = function(){
                var handlerName = "_" + event;
                if(this.get(handlerName)){
                    this.sendAction(handlerName, this.get("param"));    
                }
            }
        });

        return definition;
    }()
);

// templates/components/evented-tag.hbs
{{yield}}
以及使用:

// templates/components/project_picker.hbs
<ul>
    {{#each project in projects}}
        {{#evented-tag tagName="li" param=project _mouseEnter="projectHovered", _click="projectClicked"}}
            {{project.name}}
        {{/evented-tag}}
    {{/each}}
</ul>

// components/project_picker.js
export default Ember.Component.extend({
 actions: {
    projectClicked: function(project){
        console.log("projectClicked");
        console.log(project);
    },

    projectHovered: function(project){
        console.log("projectHovered");
        console.log(project);
    }       
 }
});
//模板/组件/项目\u picker.hbs
    {{{#项目中的每个项目} {{{#事件标记标记名=“li”param=project{u mouseEnter=“projecthover”,{u click=“projectClicked”} {{project.name} {{/事件标记} {{/每个}}
//组件/项目_picker.js 导出默认的Ember.Component.extend({ 行动:{ 点击项目:功能(项目){ console.log(“projectClicked”); console.log(项目); }, 项目悬停:功能(项目){ console.log(“项目悬停”); console.log(项目); } } });
好这是一个更通用的解决方案,用于在父视图中触发操作并在上下文中传递

// components/evented-tag.js
export default Ember.Component.extend(
    function(){
        var definition = {
            template: Ember.Handlebars.compile('{{yield}}'),
        };

        var events = Ember.A(["touchStart", "touchMove", "touchEnd", "touchCancel", "keyDown", "keyUp", "keyPress", "mouseDown", "mouseUp", "contextMenu", "click", "doubleClick", "mouseMove", "focusIn", "focusOut", "mouseEnter", "mouseLeave", "submit", "change", "dragStart", "drag", "dragEnter", "dragLeave", "dragOver", "drop", "dragEnd"]);

        var self = this;
        events.forEach(function(event){
            definition[event] = function(){
                var handlerName = "_" + event;
                if(this.get(handlerName)){
                    this.sendAction(handlerName, this.get("param"));    
                }
            }
        });

        return definition;
    }()
);

// templates/components/evented-tag.hbs
{{yield}}
以及使用:

// templates/components/project_picker.hbs
<ul>
    {{#each project in projects}}
        {{#evented-tag tagName="li" param=project _mouseEnter="projectHovered", _click="projectClicked"}}
            {{project.name}}
        {{/evented-tag}}
    {{/each}}
</ul>

// components/project_picker.js
export default Ember.Component.extend({
 actions: {
    projectClicked: function(project){
        console.log("projectClicked");
        console.log(project);
    },

    projectHovered: function(project){
        console.log("projectHovered");
        console.log(project);
    }       
 }
});
//模板/组件/项目\u picker.hbs
    {{{#项目中的每个项目} {{{#事件标记标记名=“li”param=project{u mouseEnter=“projecthover”,{u click=“projectClicked”} {{project.name} {{/事件标记} {{/每个}}
//组件/项目_picker.js 导出默认的Ember.Component.extend({ 行动:{ 点击项目:功能(项目){ console.log(“projectClicked”); console.log(项目); }, 项目悬停:功能(项目){ console.log(“项目悬停”); console.log(项目); } } });
啊,我想我还想从li中捕获点击。不幸的是,您不能在同一个元素上使用多个操作,所以我认为这是不可能的?啊,只创建一个自定义视图我已经为组件创建了一个自定义视图,创建另一个视图只是为了传播一个事件似乎有点过分没有?我的意思是,如果我遵循这种模式,当我只想将元素上的事件绑定到组件中的动作时,我将创建大量的自定义视图。我添加了另一个答案,其中展示了如何使用通用自定义视图,允许从组件中的元素传播任何事件。我完全理解,在组件上使用视图的好处是块功能(也就是说,您可以非常轻松地更改视图中的html),这是一个很好的观点。我对它进行了修改,以允许块格式。啊,我应该知道,我还想捕获来自li的点击。不幸的是,您不能在同一个元素上使用多个操作,所以我认为这是不可能的?啊,只创建一个自定义视图我已经为组件创建了一个自定义视图,创建另一个视图只是为了传播一个事件似乎有点过分没有?我的意思是,如果我遵循这种模式,当我只想将元素上的事件绑定到组件中的动作时,我将创建大量的自定义视图。我添加了另一个答案,其中展示了如何使用通用自定义视图,允许从组件中的元素传播任何事件。我完全理解,在组件上使用视图的好处是块功能(也就是说,您可以非常轻松地更改视图中的html),这是一个很好的观点。我修改了它,允许块格式。唯一的问题是