2013-02-16 52 views
1

在我们的应用程序中,我们用jQuery插件替换标准选择,以便能够在CSS中选择样式。我试图让它与Ember一起工作,但我的解决方案非常肮脏。有没有适当的方法来做到这一点?Ember.Select自定义<select>插件:如何绑定这两个?

我认为关键的问题是这种插件需要在页面中呈现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

我知道你不需要听值换,因为selectBox已经主动更新两者的DOM元素,也是插件本身。 valueChanged观察员中的简单跟踪可以告诉你很多事情。

根据你的问题,我拿出这个小片段。事实上,我认为它实际上就像你原来的方法。

jsFiddle example

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它,因为你将需要等待的内容首先被渲染。刷新不应该太重。

+0

非常感谢Lionel的帮助!不幸的是,它不起作用,至少不完全。我的目标是要有一个“全面”的约束力。我的意思是,如果你以编程方式改变选择本身,它也应该改变选择框。这就是为什么 - 我认为 - 你需要观察'价值'。我分叉你的jsFiddle,请看这里:http://jsfiddle.net/4xxLA/。 – PJC 2013-02-17 13:07:04

+0

错误的链接,对不起:http://jsfiddle.net/4xxLA/1/(续)如果您更改了选择控件本身(而不是选择框),您将看到该更改未应用于选择框。另外,当您更改选择内容时,“选定”字段不会更新。 – PJC 2013-02-17 13:13:15