2012-04-01 17 views
5

我已經做了選擇了一個樣本Ember.js集成(https://github.com/harvesthq/chosen)Ember.js所選的積分

的CoffeeScript:

App.ChosenSelectView = Em.Select.extend({ 
    didInsertElement: -> 
    @_super() 
    @$().chosen() 
    # Assumes optionLabelPath is something like "content.name" 
    @addObserver(@get("optionLabelPath").replace(/^content/, "[email protected]"), -> @contentDidChange()) 
    contentDidChange: -> 
    # 2 ticks until DOM update 
    Em.run.next(this, (-> Em.run.next(this, (-> @$().trigger("liszt:updated"))))) 
}) 

事情困擾我的是,我沒有多少時間做我所選擇的插件觸發更新前需要一個好主意。從我的實驗來看,2個運行循環是可以的,但是對於整個事情來說也許有更好的辦法?在的jsfiddle

完整的示例:http://jsfiddle.net/oruen/qfYPy/

回答

7

我認爲問題是,你的觀察者通知樣的太早,這意味着變化還沒有被寫入到DOM。

我身邊砍死了一點,最後我想出了一個解決方案,這爲chosen插件事件被觸發之前調用Ember.run.sync(),看到http://jsfiddle.net/pangratz666/dbHJb/

把手

<script type="text/x-handlebars" data-template-name="selectTmpl" > 
    {{#each items tagName="select" }} 
     <option {{bindAttr value="id"}} >{{name}}</option>  
    {{/each}} 
</script>​ 

的JavaScript

App = Ember.Application.create({}); 

App.items = Ember.ArrayProxy.create({ 
    content: [Ember.Object.create({ 
     id: 1, 
     name: 'First item' 
    }), Ember.Object.create({ 
     id: 2, 
     name: 'Second Item' 
    })] 
}); 

Ember.View.create({ 
    templateName: 'selectTmpl', 
    itemsBinding: 'App.items', 

    didInsertElement: function() { 
     this.$('select').chosen(); 
    }, 

    itemsChanged: function() { 
     // flush the RunLoop so changes are written to DOM? 
     Ember.run.sync(); 
     // trigger the 'liszt:updated' 
     Ember.run.next(this, function() { 
      this.$('select').trigger('liszt:updated'); 
     }); 
    }.observes('[email protected]') 
}).append(); 

Ember.run.later(function() { 
    // always use Ember.js methods to acces properties, so it should be 
    // `App.items.objectAt(0)` instead of `App.items.content[0]` 
    App.items.objectAt(0).set('name', '1st Item'); 
}, 1000);​ 
+0

我不知道是否有你需要的一切Ember.ru *在你的代碼中調用。我刪除它們,它的工作原理。我錯過了什麼 ? – 2012-04-03 07:19:10

+0

感謝您的回答,我認爲run.sync()方法更好,然後在完成同步之前猜測循環數。 – oruen 2012-04-03 12:59:44

4

邁克爾·格羅瑟張貼在這裏他的工作ChosenSelectView:http://grosser.it/2012/05/05/a-chosen-js-select-filled-via-ember-js

+1

雖然這可能在理論上回答這個問題,[這將是更可取的](http://meta.stackexchange.com/q/8259)在這裏包括答案的基本部分,並提供參考鏈接。 – 2012-05-05 13:18:51

+0

從Ember.js 1.0.0.rc4開始,這並不能代替Ember.Select,如果你能得到它,請發佈jsfiddle。 – Intentss 2013-06-06 16:34:38

0

這可能會爲你工作的灰燼1.0和所選擇v0.12:

的JavaScript:

App.ChosenSelect = Ember.Select.extend({ 
    chosenOptions: {width:'100%', placeholder_text_multiple: 'Select Editors', search_contains: true}, 
    multiple:true, 
    attributeBindings:['multiple'], 

    didInsertElement: function(){ 
    var view = this; 
    this._super(); 
    view.$().chosen(view.get('chosenOptions')); 

    // observes for new changes on options to trigger an update on Chosen 
    return this.addObserver(this.get("optionLabelPath").replace(/^content/, "[email protected]"), function() { 
     return this.rerenderChosen(); 
    }); 

    }, 
    _closeChosen: function(){ 
    // trigger escape to close chosen 
    this.$().next('.chzn-container-active').find('input').trigger({type:'keyup', which:27}); 
    }, 

rerenderChosen: function() { 
    this.$().trigger('chosen:updated'); 
    } 
}); 

把手:

{{view App.ChosenSelect 
    contentBinding="options" 
    valueBinding="selectedOption" 
    optionLabelPath="content.name" 
}} 
+0

這不處理值綁定。例如,如果我在我的模型上調用方法回滾,則選擇的值不會更改。 – 2014-04-10 19:30:07