5

Chosen (https://github.com/harvesthq/chosen) との Ember.js 統合のサンプルを作成しました。

コーヒースクリプト:

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

私を悩ませているのは、Chosen ウィジェットの更新をトリガーする前に、どのくらいの時間が必要かについてよくわからないことです。私の実験から、2回の実行ループは問題ありませんが、全体にもっと良い方法があるのでしょうか?

jsfiddle の完全な例: http://jsfiddle.net/oruen/qfYPy/

4

3 に答える 3

7

問題は、オブザーバーへの通知が早すぎること、つまり、変更がまだ DOM に書き込まれていないことだと思います。

私は少しハックして、最終的に、プラグインEmber.run.sync()のイベントがトリガーされる前に呼び出すソリューションを思いつきました。http://jsfiddle.net/pangratz666/dbHJb/を参照してくださいchosen

ハンドルバー:

<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('items.@each.name')
}).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);​
于 2012-04-02T18:29:31.080 に答える
4

Michael Grosserは、作業中のChosenSelectViewをここに投稿しました:http://grosser.it/2012/05/05/a-chosen-js-select-filled-via-ember-js

于 2012-05-05T10:48:24.257 に答える
0

これは、Ember 1.0 および Chosen 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/, "content.@each"), 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"
}}
于 2013-09-10T06:21:25.287 に答える