2012-04-01 13 views
5

que he hecho una integración Ember.js muestra con Elegido (https://github.com/harvesthq/chosen)Ember.js Elegido integración

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

Lo eso me molesta es que no tengo una buena idea de cuánto tiempo necesito antes de activar la actualización en el widget elegido. De mis experimentos 2 ejecutar bucles está bien, pero tal vez hay una mejor manera para todo esto?

ejemplo completo en jsFiddle: http://jsfiddle.net/oruen/qfYPy/

Respuesta

7

creo que el problema es que su observador se notifica tipo de demasiado pronto, lo que significa que los cambios aún no se han escrito en el DOM.

He hackeado un poco alrededor y al final se me ocurrió una solución, que llama Ember.run.sync() antes del evento para el chosen complemento se activa, véase http://jsfiddle.net/pangratz666/dbHJb/

Manillar:

<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

Me pregunto si es necesario Ember.ru n. * llama a su código. Los eliminé y funciona. Me he perdido algo ? –

+0

Gracias por la respuesta, creo que el enfoque run.sync() dado es mejor que adivinar el número de bucles antes de completar la sincronización. – oruen

4

Michael Grosser publicó su trabajo ChosenSelectView aquí: http://grosser.it/2012/05/05/a-chosen-js-select-filled-via-ember-js

+1

Si bien esto podría responder teóricamente a la pregunta, [sería preferible] (http://meta.stackexchange.com/q/8259) incluir aquí las partes esenciales de la respuesta y proporcionar el enlace de referencia. –

+0

A partir de Ember.js 1.0.0.rc4 esto no funciona como un reemplazo en sustitución de Ember.Seleccione, si puede hacerlo funcionar, publique el jsfiddle. – Intentss

0

esto podría funcionar para usted en Ember 1.0 y v0.12 Elegido:

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'); 
    } 
}); 

Manillar:

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

Esto no está manejando el enlace de valor. Por ejemplo, si invoco la reversión de método en mi modelo, el valor elegido no cambia. –