本文介绍了Ember.js选择整合的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经做了一个样例Ember.js与Chosen的集成(https://github.com/harvesthq/chosen)



Coffeescript: strong>

  App.ChosenSelectView = Em.Select.extend({
didInsertElement: - >
@_super()
@ $()。selected()
#假设optionLabelPath类似于content.name
@addObserver(@get(optionLabelPath)。replace(/内容/,内容@每个), - > @contentDidChange())
contentDidChange: - >
#2打勾直到DOM更新
Em.run.next(this, ( - > Em.run.next(this,( - > @ $()。trigger(liszt:updated)))))
})

令我烦恼的是我在触发更新小选程序之前需要多少时间。从我的实验2运行循环是好的,但也许有一个更好的方式为整个事情?



完整的例子在jsfiddle:

解决方案

我认为问题是你的观察者被通知太早了,这意味着这些变化还没有被写入DOM。



我已经被黑了一点,最后我想出了一个解决方案,在的事件之前调用 Ember.run.sync()已选择插件,请参阅



Handlebars

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

strong> 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')。selected();
},

itemsChanged:function(){
//刷新RunLoop,写入DOM?
Ember.run.sync();
//触发'liszt:updated'
Ember.run.next(this,function(){
this 。$('select')。trigger('liszt:updated');
});
} .observes('items。@ each.name')
})。append );

Ember.run.later(function(){
//总是使用Ember.js方法来访问属性,所以应该是
//`App.items.objectAt (0)`而不是`App.items.content [0]`
App.items.objectAt(0).set('name','1st Item');
},1000);


I've done a sample Ember.js integration with Chosen (https://github.com/harvesthq/chosen)

Coffeescript:

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")))))
})

The thing that bothers me is I don't have a good idea about how much time do I need before triggering update on the Chosen widget. From my experiments 2 run loops is ok, but maybe there is a better way for the whole thing?

Full example at jsfiddle: http://jsfiddle.net/oruen/qfYPy/

解决方案

I think the problem is that your observer is notified kind of too early, meaning that the changes have not yet been written to the DOM.

I've hacked a little around and in the end I came up with a solution, which calls Ember.run.sync() before the event for the chosen plugin is triggered, see http://jsfiddle.net/pangratz666/dbHJb/

Handlebars:

<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);​

这篇关于Ember.js选择整合的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-01 18:53