nytimes / backbone.stickit

Backbone data binding, model binding plugin. The real logic-less templates.
MIT License
1.64k stars 176 forks source link

Using equality operator instead of identity operator for select field #300

Closed marcinjackowiak closed 8 years ago

marcinjackowiak commented 8 years ago

I'm having an issue when i bind a select and retrieve a backbone model with value that is an integer.

The select is pre-populated:

<select name="schedule_id">
<option value="1">Schedule 1</option>
<option value="2">Schedule 2</option>
</select>

The binding is added using addBinding method:

var selector = 'select[name=schedule_id]';
view.addBinding(null, selector, name);

The json returned from the server is:

{"success":true,"data":{"schedule_id":2}}

The select on the page does not reflect the correct schedule, it still shows Schedule 1 as selected.

The problem appears to be with the comparison on the following line (~line 569) since the data types are different:

if (!isMultiple && optionVal != null && fieldVal != null && optionVal === fieldVal) {

I'm able to get it to work correctly after changing the line to use the less strict equality operator.

if (!isMultiple && optionVal != null && fieldVal != null && optionVal == fieldVal) {

Is there a better way to handle this situation? I do not want to change the data type to string for the data coming from the server since integer is the correct data type reflecting the actual value.

blikblum commented 8 years ago

I overcome this situation using getter and setter:

bindings: {    
    '[name=price]': {
      observe: 'price',
      onGet: 'numToStr',
      onSet: 'strToNum' 
    },
    '[name=quantity]': {
      observe: 'quantity',
      onGet: 'numToStr',
      onSet: 'strToNum' 
    }
  }
   //later:
   strToNum: function (val) {
      if (val != null) {
        return +val;
      }
    },
    numToStr: function (val) {
      if (val != null) {
        return val.toString();
      }
    }
marcinjackowiak commented 8 years ago

Thanks, that did the trick. For anyone interested, I'm doing all the binding dynamically so this is the code i used:

        view.addBinding(null, selector, {
            observe: name,
            onGet: function(val) {
                if(val != null) {
                    return val.toString();
                }
            },
            onSet: function(val) {                                
                return +val;
            }
        });