简体   繁体   中英

Recreating Bootstrap Dropdown functionality in Ember.js

Edit: Looking for a way to close the dropdown when anything but the button is clicked: http://jsfiddle.net/brennan/s4JTn/

I'm looking to (re)create twitter's dropdown menu in my ember app. I'm specifically having an issue trying to close the dropdown when anything except the dropdown is clicked. Ie. I'm looking for a way to add an event listener to my app to close my dropdown when the body of the app is clicked.

Here's my (child) view.

categorySelect: Ember.View.extend({
    isOpen: false,
    selected: /* removed for brevity */,
    content:[
        /* removed for brevity */
        /* follows structure: {slug: 1, title: 'title', isActive: true} */
    ],

    dropdownToggle: function(e){
        var open = this.get('isOpen');
        if(open){
            this.set('isOpen', false);
        }else{
            this.set('isOpen', true);
        }
    },
    select: function(e){
        var selected = e.context;

        this.content.setEach('isActive', false);

        this.set('selected', selected);
        selected.set('isActive', true);

        this.set('isOpen', false);
    }
})

and here is my template code...

{{#view categorySelect tagName="div" class="btn-group" classBinding="isOpen:open"}}
                        <a class="btn dropdown-toggle btn-facebook btn-small" {{action "dropdownToggle" on="click"}} href="#">
                            {{selected.title}}
                            <span class="caret"></span>
                        </a>
                        <ul class="dropdown-menu pull-right">
                            {{#each content}}
                            <li {{bindAttr class="isActive:active"}}><a href="#" {{action "select" on="click"}}>{{title}}</a></li>
                            {{/each}}
                        </ul>
                    {{/view}}

I've tried adding event listeners to the body like the following which isn't working. Ember seems to stop propagation if I click on any ember views. So while it works if I click directly on the body, it doesn't work if i click on any of my views :(

didInsertElement: function(){
        var self = this;
        $('body').on('click', function(){
            self.set('isOpen', false);
        });
    },

Looking for help and advice. Also, if any of the above code looks like crap please let me know I'm looking to learn as much as I can.

I have roughly the same setup as you that works by creating an event listener on the body element using didInsertElement as well.

Only difference is I have a e.stopPropagation() call in dropdownToggle:

dropdownToggle: function(e){
    // [removed]
    e.stopPropagation();
},

Without that line, I was unable to keep the dropdown open, as the click on the dropdown propagates to the body and immediately closes it.

On my setup, clicks on views do propagate to the body (hence the above code), and clicking on other views does trigger the event listener on the body.

My guess is you have some code in your other views stopping the propagation to the body?

Try http://jsfiddle.net/bjaeP/ for an example.

I have modified your fiddle : http://jsfiddle.net/tV8X6/

This works for me. Just removed the action helper for 'dropdownToggle' and added data attribute to the a tag, and added 'dropdown' class for your 'categorySelect' view

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM