gmac / backbone.epoxy

Declarative data binding and computed models for Backbone
http://epoxyjs.org
MIT License
615 stars 89 forks source link

Setting attribute value to undefined through bindingFilters #139

Open jekuno opened 8 years ago

jekuno commented 8 years ago

The current implementation of the integer bindingFilter returns 0 for empty strings which is ok. see: https://github.com/gmac/backbone.epoxy/blob/master/backbone.epoxy.js#L962

I want to add a bindingFilter which returns undefined for empty input fields (i.e. empty strings). It looks like this (CoffeeScript):

bindingFilters:
  integerOrUndefined:
    get: (value) ->
      if value then parseInt(value, 10) else undefined

     set: ( value ) ->
      if value then parseInt(value, 10) else undefined

If I use this bindingFilter and the user enters integers to the input fields the attribute value gets set correctly. If the user clears the input field the set function also correctly gets triggered and returns undefined as expected. However the according attribute never gets set to undefined.

I think this issue is due to a special handling of undefined values in backbone.epoxy. Is there any workaround for this?

jekuno commented 8 years ago

I found the reason for this bug. The isUndefined check in line https://github.com/gmac/backbone.epoxy/blob/v1.3.1/backbone.epoxy.js#L870 prevents undefined values from being set. (Also because of this no change events are sent when changing a value to undefined using the set function of a bindingFilter).

I currently use the following workaround:

bindingFilters:
    integerOrUndefined:
      get: (value) ->
        value

      set: ( value ) ->
          parseInt(stringValue, 10)

The set function of the above workound returns NaN for empty strings or strings which cannot be passed using parseInt. The getter returns this NaN value to the view which gets displayed as an empty form field in turn (if needed you can also convert NaN values to undefined in the get function).