您可能希望 JQ.Widget 看起来像这样,警告它不漂亮:
这里,JQ.UiBase 和 JQ.Widget 是一样的
JQ.UiBase = Ember.Mixin.create({
uiWidgets: {},
uiAttributes: {},
// ----------------------------------------------------------------------------
// setup and teardown
didInsertElement: function(){
this._super();
this._createUiWidgets();
},
willDestroyElement: function(){
this._super();
// implement tear down
},
// ----------------------------------------------------------------------------
// @Private
// @Function: for each $.ui specified in the view, create a $.ui widget
// add ui widgets to uiWidgets hash, ui widget setting to uiAttributes hash
_createUiWidgets: function(){
var widgetTypes = this._gatherWidgetTypes();
uiWidgets = this.get('uiWidgets'),
uiAttributes = this.get('uiAttributes'),
thisView = this;
widgetTypes.forEach( function( widget ){
var options = thisView.get( widget + 'Options' ) || {},
handlers = thisView._registerEventHandlers( widget ),
attributes = $.extend( options, handlers ),
uiWidget = $.ui[widget]( attributes, thisView.$() );
uiWidgets[widget] = uiWidget;
uiAttributes[widget] = attributes;
});
},
// @Function: collects named $.ui events from Widget mixin
// for each event, if there is an associated callback, wrap it in a function and call the view's context
// @Return: a hash map $.ui event to callback function defined in view
_registerEventHandlers: function( widget_name ){
var widgetName = widget_name + 'Events',
events = this.get( widgetName ) || [],
thisView = this,
eventHandlers = {};
if ( events.length === 0 ) return;
// note the iterator is not scoped to the view
events.forEach( function( event ){
var callBack = thisView.get( event );
if ( callBack ){
eventHandlers[ event ] = function ( event, ui ){ callBack.call( thisView, event, ui ); };
};
});
return eventHandlers;
},
// TODO --> find alternate implementation that does not break if structure of ui mixins or namespace change
_gatherWidgetTypes: function() {
var nameSpace = 'JQ',
widgetTypes = [];
Ember.Mixin.mixins(this).forEach( function( mixin ){
// find widget with correct namespace
if ( mixin.toString().substring(0,2) === nameSpace ){
// console.log( 'gather: ', mixin, ' --> ', mixin.mixins[1] )
// access widget mixin and check widget mixin have properties
if ( mixin.mixins && mixin.mixins[1] && mixin.mixins[1].properties ){
if ( mixin.mixins[1].properties.widgetType ) widgetTypes.push( mixin.mixins[1].properties.widgetType)
}
}
});
return widgetTypes;
},
});
然后你的可调整大小的 mixin 看起来像这样:
JQ.Resizable = Ember.Mixin.create( JQ.UiBase, {
widgetType: 'resizable',
resizableOptions: { 'aspectRatio': 1/1 },
resizableEvents: [ 'resize' ],
resize: function( event, ui ){
// do stuff
},
});
这里最重要的函数是_gatherWidgetTypes
,它将所有 JQ 命名空间的 mixin 收集到 ember 对象中。在我看来,这有点像 hack,我最终没有使用 JQ.UiBase 在制作它之后,倾向于混合逻辑来创建小部件并将事件处理程序和选项指定到一个 mixin 中,最终看起来更干净,但这就是只有我。