在我们的应用程序中,我们用jQuery插件替换标准选择,以便能够在CSS中设置样式。我试图让它与Ember合作,但我的解决方案真的很脏。有没有正确的方法来做到这一点?
我认为关键问题是这种插件需要在页面中呈现HTML才能自行更新。然而,在实际在页面中呈现HTML之前,Ember绑定会触发。
Ember.Select.reopen({
didInsertElement: function(){
this.$().selectBox(); // Create the jQuery plugin
},
valueChanged: function(){
this.$().selectBox('value', this.get('value')); // Update the plugin value
}.observes('value'),
contentChanged: function(){
this.set('value', "-10"); // Fake value, just to force the cache. Othwerwise it won't refresh if the previous value was also "0".
this.set('value', "0"); // Default value for the new content.
// Option 1: manually "re-create" the plugin using 'content' - it fails with:
// Uncaught Error: Cannot perform operations on a Metamorph that is not in the DOM.
// And anyway it means 'content' needs to have a specific format which is not great.
var contentAsJson = {};
this.get('content').forEach(function(val){contentAsJson[val.get('id')] = val.get('displayName')});
this.$().selectBox('destroy');
this.$().selectBox();
this.$().selectBox('options', contentAsJson);
this.$().selectBox('value', this.get('value'));
// Options 2: wait for the actual HTML to be rendered with a timer. It "works" but it is terrible I guess
// to rely on a timer.
var self = this.$();
setTimeout(function(){self.selectBox('refresh')}, 100);
}.observes('content')
});
答案 0 :(得分:0)
我意识到你不需要听价值转换器,因为selectBox
已经在主动更新dom元素和插件本身。 valueChanged
观察者中的一个简单的痕迹可以告诉你很多事情。
根据您的问题,我推出了这个小片段。事实上,我认为它实际上就像你原来的方法。
Ember.Select.reopen({
didInsertElement: function(){
this.set('value', null);
this.$().selectBox(); // Create the jQuery plugin
},
contentChanged: function() {
//Ember.run.next is equivalent to setTimeout(fn,1);
//We want to wait for contentChanged first to finish
//then rerender selectBox.
//To get the structure of key-value is too tedious so
//just rerender it instead.
Ember.run.next(this, function() {
this.$().selectBox('refresh');
});
//Reset the selection value if you insist
//this.set('value', null);
}.observes('content')
});
我认为只需要setTimeout
即可,因为您需要等待首先呈现内容。刷新不应该太重。