Edit in JSFiddle

var MyApp = angular.module('MyApp', [], function() {});

/**
 * Shakes the element using jQuery UI shake if expression is truthy.
 *
 * Usage:
 *   <ANY shake="{expr}" [after-shake="{expr}"]>...</ANY>
 */
MyApp.directive('shake', function() {
  return function(scope, elem, attrs) {
    scope.$watch(attrs.shake, function(shake, wasShaking) {
      if(shake && !wasShaking) {
        elem.effect('shake', function() {
          attrs.afterShake !== undefined && scope.$apply(function() {
            scope.$eval(attrs.afterShake);
          });
        });
      }
    });
  };
});

function MainCtrl($scope) {
  $scope.foo = 'baz';
}
<script type="text/javascript" src="http://code.jquery.com/jquery-1.9.0.min.js"></script>
<script type="text/javascript" src="https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.core.js"></script>
<script type="text/javascript" src="https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.effect.js"></script>
<script type="text/javascript" src="https://raw.github.com/jquery/jquery-ui/master/ui/jquery.ui.effect-shake.js"></script>
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/angularjs/1.0.3/angular.min.js"></script>

<div ng-app="MyApp" ng-controller="MainCtrl">
  <div>
    <p>This one uses &lt;option /&gt; elems; the model value is destroyed by our jQuery UI effect (try the button below).</p>
    <select ng-model="foo" shake="doShake" after-shake="doShake = false">
      <option value="bar">bar</option>
      <option value="baz">baz</option>
    </select>
  </div>
  <div>
    <p>This one uses ng-options and the model value is preserved as desired.</p>
    <select ng-model="foo" shake="doShake" after-shake="doShake = false"
            ng-options="value for value in ['bar', 'baz']"></select>
  </div>
  <div>
    <button ng-click="doShake = true" ng-hide="doShake">Shake the selects</button>
  </div>
</div>
div+div {
  margin-top: 15px;
}