Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
573 views
in Technique[技术] by (71.8m points)

twitter bootstrap - How can I make an Alert Notifications component using Ember.js?

I want to include Alert Notifications in my Ember.js application like Bootstrap Alerts http://getbootstrap.com/javascript/#alerts but I want to be able to control the creation or destruction of notification objects instead of Bootstrap so I have more "Ember control" over the objects.

How can I write an Ember.js Component to do this instead of using the Bootstrap JavaScript?

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

See a working demo here: http://jsbin.com/ceseku/3/edit?html,css,js,output

Component

Logic

/**
 * Notifications Manager of Notifications Widget
 * Object which manages incoming transactions and provides
 * access to App.Notification which can not be directly
 * accessed.
 *
 * @example
 *  App.NotificationsManager.push({type: 'error', msg: 'Unable to persist comment'});
 *  App.NotificationsManager.push({msg: 'Unable to persist comment'});
 *  App.NotificationsManager.push('Plain message');
 */
App.NotificationsManager = Ember.Object.create({

    /**
     * Array store for message objects
     * type {Array}
     */
    content: Ember.A(),

    /**
     * @param options {Object} the message object containing msg and type
     */
    push: function(options) {
        var self = this,
            message,
            type;   // success|warning|error|info

        if (!Boolean(arguments)) return;

        if (typeof options === 'object' && options.msg) {
            message = options.msg;
            type = options.type || 'warning';
        } else if (typeof options === 'string') {
            message = options;
            type = 'warning';
        } else {
            return false;
        }

        self.get('content').pushObject({
            type: type,
            message: message
        });
    }

});


/**
 * A collection of Notification Items of Notification Widget
 * @requires App.NotificationsManager
 */
App.NotificationsListComponent = Ember.Component.extend({

    classNames: ['Notifications'],

    tagName: 'section',

    content: App.NotificationsManager.get('content')

});


/**
 * A Notification Item of Notification Widget
 * @requires App.NotificationsListComponent
 */
App.NotificationsListItemComponent = Ember.Component.extend({

    classNames: ['Notifications__item', 'alert', 'alert-dismissible'],

    classNameBindings: ['typeClass'],

    item: null,

    typeClass: function() {
        return 'alert-' + this.get('item.type');
    }.property('item.type'),

    isSuccess: function() {
        return this.get('item.type') === 'success';
    }.property('item.type'),

    duration: 6000,

    timer: null,

    showNotification: function(time) {
        var self = this;
        self.set('timer', window.setTimeout(function() {
            self.clearNotification();
            self.clearTimeout();
        }, time));
    },

    clearNotification: function() {
        this.$().fadeOut();
        App.NotificationsManager.get('content').removeObject(this.get('content'));
        this.set('timer', null);
    },

    clearTimeout: function() {
        var self = this;
        if (self.get('timer') !== null) {
            window.clearTimeout(self.get('timer'));
            self.set('timer', null);
        }
    },

    didInsertElement: function() {
        var self = this;
        this.showNotification(self.get('duration'));
    },

    mouseEnter: function() {
        this.clearTimeout();
    },

    mouseLeave: function() {
        var halfSpeedTime = this.get('duration') / 2;
        this.showNotification(halfSpeedTime);
    },

    actions: {
        clear: function() {
            this.clearNotification();
        }
    }

//  willDestroyElement: function() {
//  }

});

Templates

<script type="text/x-handlebars" data-template-name="components/notifications-list">
    {{#each notification in content}}
        {{notifications-list-item item=notification}}
    {{/each}}
  </script>

  <script type="text/x-handlebars" data-template-name="components/notifications-list-item">
    <div class="Notifications__item__icon">
        {{#if isSuccess}}
            <i class="glyphicon glyphicon-ok-sign info-icon"></i>
        {{else}}
            <i class="glyphicon glyphicon-question-sign info-icon"></i>
        {{/if}}
    </div>

    <div class="Notifications__item__main">
        <span>{{item.message}}</span>
    </div>

    <button type="button" class="Notifications__item__close close" {{action "clear"}}><span aria-hidden="true">&times;</span><span class="sr-only">Close</span></button>
  </script>

Styles

.Notifications {
    position: fixed;
    top: 20px;
    right: 50%;
    left: 50%;
    margin-left: -200px;
    z-index: $zindex-navbar-fixed;
    width: 400px;   
}

.Notifications .info-icon {
    margin-right: 6px;
}

.Notifications__item {
    display: table;
    cursor: pointer;
    box-shadow: 0 3px 3px rgba(black, .16), 0 3px 3px rgba(black, .23);  
    width: 90%;
    margin-left: auto;
    margin-right: auto;
}

.Notifications__item__icon,
.Notifications__item__main,
.Notifications__item__close {
    display: table-cell;
    vertical-align: top;
}

.Notifications__item__icon {
    width: 26px;
}

.Notifications__item__main span {
        word-wrap: break-word;
        text-wrap:none;
    }
}

.Notifications__item__close {
    width: 20px;
    text-align: right;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...