function _updateJQueryDataCache ( $elem ) {
        var add = {},
            remove = [];

        if ( $.hasData( $elem[0] ) ) {

            // A jQuery data cache exists. Update it for the el properties (and attribute names registered by a plugin).

            // Primitive data types. Normally, this will read the "data-tag-name", "data-class-name" and "data-id"
            // attributes.
            _.each( registeredDataAttributes.primitives, function ( attributeName ) {
                var attributeValue = $elem.attr( "data-" + attributeName );

                if ( attributeValue === undefined ) {
                    remove.push( attributeName );
                } else {
                    add[toCamelCase( attributeName )] = attributeValue;
                }
            } );

            // Stringified JSON data. Normally, this just deals with "data-attributes".
            _.each( registeredDataAttributes.json, function ( attributeName ) {
                var attributeValue = $elem.attr( "data-" + attributeName );

                if ( attributeValue === undefined ) {
                    remove.push( attributeName );
                } else {

                    try {
                        add[toCamelCase( attributeName )] = $.parseJSON( attributeValue );
                    } catch ( err ) {
                        remove.push( attributeName );
                    }

                }
            } );

            if ( remove.length ) $elem.removeData( remove );
            if ( _.size( add ) ) $elem.data( add );
        }

    }
function _updateJQueryDataCache ( $elem ) {
        var add = {},
            remove = [];

        if ( $.hasData( $elem[0] ) ) {

            // A jQuery data cache exists. Update it for the el properties (and attribute names registered by a plugin).

            // Primitive data types. Normally, this will read the "data-tag-name", "data-class-name" and "data-id"
            // attributes.
            _.each( registeredDataAttributes.primitives, function ( attributeName ) {
                var attributeValue = $elem.attr( "data-" + attributeName );

                if ( attributeValue === undefined ) {
                    remove.push( attributeName );
                } else {
                    add[toCamelCase( attributeName )] = attributeValue;
                }
            } );

            // Stringified JSON data. Normally, this just deals with "data-attributes".
            _.each( registeredDataAttributes.json, function ( attributeName ) {
                var attributeValue = $elem.attr( "data-" + attributeName );

                if ( attributeValue === undefined ) {
                    remove.push( attributeName );
                } else {

                    try {
                        add[toCamelCase( attributeName )] = $.parseJSON( attributeValue );
                    } catch ( err ) {
                        remove.push( attributeName );
                    }

                }
            } );

            if ( remove.length ) $elem.removeData( remove );
            if ( _.size( add ) ) $elem.data( add );
        }

    }
function _updateJQueryDataCache ( $elem ) { var add = { } , remove = [ ] ; if ( $ . hasData ( $elem [ 0 ] ) ) { // A jQuery data cache exists. Update it for the el properties (and attribute names registered by a plugin). // Primitive data types. Normally, this will read the "data-tag-name", "data-class-name" and "data-id" // attributes. _ . each ( registeredDataAttributes . primitives , function ( attributeName ) { var attributeValue = $elem . attr ( "data-" + attributeName ) ; if ( attributeValue === undefined ) { remove . push ( attributeName ) ; } else { add [ toCamelCase ( attributeName ) ] = attributeValue ; } } ) ; // Stringified JSON data. Normally, this just deals with "data-attributes". _ . each ( registeredDataAttributes . json , function ( attributeName ) { var attributeValue = $elem . attr ( "data-" + attributeName ) ; if ( attributeValue === undefined ) { remove . push ( attributeName ) ; } else { try { add [ toCamelCase ( attributeName ) ] = $ . parseJSON ( attributeValue ) ; } catch ( err ) { remove . push ( attributeName ) ; } } } ) ; if ( remove . length ) $elem . removeData ( remove ) ; if ( _ . size ( add ) ) $elem . data ( add ) ; } }
Reads registered data attributes of a given element from the DOM, and updates an existing jQuery data cache with
these values.

If no jQuery data cache exists, it is NOT created by the call. (This function is meant to be used as an efficient,
internal tool.) If you need to make sure the jQuery data cache is current and in sync with the DOM, and also
create it if it doesn't exist, just call _getDataAttributes() instead.

The function is needed because jQuery keeps its own cache of data attributes, but there is no API to clear or
circumvent that cache. The jQuery functions $.fn.removeData() and $.removeData() don't do that job: despite their
name, they don't actually remove the cached values but set them to undefined. So undefined is returned on next
access - not the actual values in the DOM.

Here, we force-update the jQuery cache, making sure that changes of the HTML5 data-* attributes in the DOM are
picked up.

The implementation circumvents the numerous bugs of jQuery.fn.data(), in particular when removing data. The
behaviour and bugs of a .data() call vary by jQuery version. For an overview of that mess, see
http://jsbin.com/venuqo/4/edit?html,js,console

NB The cache update is limited to the data attributes which have been registered with _registerDataAttribute().
By default, only attributes which are "owned" by Backbone.Declarative.Views are updated - ie, the ones describing
the `el` of a view. Other HTML5 data-* attributes are not updated in the jQuery cache because it would interfere
with the responsibilities of other code.

@param   {jQuery} $elem
@returns {Object}
Reads registered data attributes of a given element from the DOM and updates an existing jQuery data cache with these values .