Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Iterating over two arrays at time without breaking bindings

Tags:

ember.js

I have a component that accepts an array of values and array of the same length with a validation error string for each value. I'd like to display a list of form fields with inputs for each value and error pair. I've tried creating a computed property like this:

var myComponent = Ember.Component.extend({
  //values: <provided array of input values>
  //errors: <provided array of error strings>
  valuesAndErrors: function() {
    var combined = [];
    for (var i = 0; i < values.length; i++) {
      combined.pushObject({
        value: this.get('values')[i],
        error: this.get('errors')[i]
      });
    }
    return combined;
  }.property('values.@each', 'errors.@each')
});

But unfortunately the changes made to values in valuesAndErrors (e.g. via {{input value=valuesAndErrors.value}}) are not pushed back to the source values array. What is the correct way to iterate over the values and errors arrays simultaneously without breaking bindings like this?

I'm currently using Ember 1.9.

like image 464
pmdarrow Avatar asked Nov 09 '22 20:11

pmdarrow


1 Answers

Instead of passing in a separate array for values and errors, why not have a computed property in the controller that combines the two and then pass that into the component?

So, your controller might look something like this:

App.ApplicationController = Ember.Controller.extend({
  values: function(){
    return ["one", "two", "three"];
  }.property(),

  errors: function(){
    return ["oneError", "twoError", "threeError"];
  }.property(),

  valuesAndErrors: function() {
    var combined = [];

    var values = this.get('values');
    var errors = this.get('errors');

    values.forEach(function(value, index){
      combined.pushObject({
        value: value,
        error: errors[index]
      });      
    });

    return combined;
  }.property('values.@each', 'errors.@each')
});

And your component template (you don't even need any component JS for this to work):

<script type="text/x-handlebars" id='components/value-error'>
  <h2>Inside of Component</h2>
    {{#each item in valuesAndErrors }}
      {{ input value=item.value }} - {{ input value=item.error }}<p/>
    {{/each}}
</script>

Working example here

UPDATE

enter image description here

like image 163
Kalman Avatar answered Jan 04 '23 03:01

Kalman