Damir Arh Damir Arh - 8 months ago 38
AngularJS Question

How to invoke a JQuery method after Angular select directive applies a model change?

I am trying to change the selection of David Stutz's bootstrap-multiselect via Angular


<select ng-model="selection" multiple="multiple" id="my-example">
<option value="cheese">Cheese</option>
<option value="tomatoes">Tomatoes</option>
<option value="mozarella">Mozzarella</option>
<option value="mushrooms">Mushrooms</option>
<option value="pepperoni">Pepperoni</option>
<option value="onions">Onions</option>

The changes to the model only get applied to the underlying
element, but the bootstrap-multiselect doesn't get updated automatically. Looking at its documentation, this is expected: you are required to call
afterwards to propagate the changes:


My question is:

How to invoke this method when the model changes after Angular is done updating the

Since I need to access the element, I assume directives are the way to go. I was looking at decorators, which in theory I could use to modify the behavior of the built-in select directive, but I don't know how to get my code invoked at the right moment.

I've prepared a plunk to demo the issue:

  • I have two multiselects bound to the same model: a bootstrap-multiselect and a plain one

  • I initialize both with a default selection

  • The first button changes the selection. The plain multiselect is updated immediatelly, but the bootstrap-multiselect appears unchanged.

  • The second button shows the current model value in an alert.

  • The third button calls
    on bootstrap-multiselect, which causes it to update. This is what I would like to get called automatically by Angular.


In the end I managed to solve my problem with a decorator. I based it on the Directive Decorator Example in AngularJS documentation.

Unlike ngHrefDirective from the example, selectDirective defines both preLink and postLink, therefore the compile override must also return both. I only needed to change postLink though, where $render is defined. In my version of the method I simply invoked the original method, which updates the select element, and called multiselect('refresh') afterwards, which was my original requirement:

app.config(['$provide', function($provide) {
  $provide.decorator('selectDirective', ['$delegate', function($delegate) {
    var directive = $delegate[0];

    directive.compile = function() {

      function post(scope, element, attrs, ctrls) {
        directive.link.post.apply(this, arguments);

        var ngModelController = ctrls[1];
        if (ngModelController) {
          originalRender = ngModelController.$render;
          ngModelController.$render = function() {

      return {
        pre: directive.link.pre,
        post: post

    return $delegate;