admin管理员组

文章数量:1302383

I have integrated the chosen plugin into my angularjs app. My app.js looks like this.

myApp.directive('chosen', function() {

    var linker = function (scope, element, attr) {
        scope.$watch('countriesList', function() {
            $('#countries').trigger('chosen:updated');
            console.log('I acctuallty get in here');
        })
        element.chosen();
    };

    return {
        restrict: 'A',
        link: linker
    };
})

my select looks like this

<div class="control-group">
  <label for ="countries" class="control-label">Countries: </label>
  <div class="controls">
    <select chosen ng-model="countries" id="countries" ng-options="country.name for country in countriesList"  data-placeholder="Select Countries" multiple class="span chzn-select"></select>  
  </div>
</div>

The problem is when the page first loads nothing is displayed in the select. The options are there when you inspect element.

The chosen:updated just doesn't seem to work. I put the console.log() in the watch and it is firing. If I run the .trigger('chosen:updated') in the browser it works perfectly. I did try element.trigger but that did not work either. So Frustrating!

I have integrated the chosen plugin into my angularjs app. My app.js looks like this.

myApp.directive('chosen', function() {

    var linker = function (scope, element, attr) {
        scope.$watch('countriesList', function() {
            $('#countries').trigger('chosen:updated');
            console.log('I acctuallty get in here');
        })
        element.chosen();
    };

    return {
        restrict: 'A',
        link: linker
    };
})

my select looks like this

<div class="control-group">
  <label for ="countries" class="control-label">Countries: </label>
  <div class="controls">
    <select chosen ng-model="countries" id="countries" ng-options="country.name for country in countriesList"  data-placeholder="Select Countries" multiple class="span chzn-select"></select>  
  </div>
</div>

The problem is when the page first loads nothing is displayed in the select. The options are there when you inspect element.

The chosen:updated just doesn't seem to work. I put the console.log() in the watch and it is firing. If I run the .trigger('chosen:updated') in the browser it works perfectly. I did try element.trigger but that did not work either. So Frustrating!

Share edited Jan 18, 2015 at 21:02 Alex Turnbull asked Jan 18, 2015 at 20:22 Alex TurnbullAlex Turnbull 2593 silver badges10 bronze badges 4
  • Does console.log inside of your $watch fire every time you make changes? Or does it fire only once? – Oleg Commented Jan 18, 2015 at 20:33
  • it fires the first time i load the page. – Alex Turnbull Commented Jan 18, 2015 at 20:35
  • You add an item to countriesList, but it does not update? – tasseKATT Commented Jan 18, 2015 at 20:48
  • No when I load the page there is nothing in the drop down – Alex Turnbull Commented Jan 18, 2015 at 20:54
Add a ment  | 

1 Answer 1

Reset to default 8

You need to let Angular (well the browser actually) render the select properly before calling chosen. You can do this by using setTimeout or Angular's $timeout.

app.directive('chosen', function($timeout) {

  var linker = function(scope, element, attr) {

    $timeout(function () {
      element.chosen();
    }, 0, false);
  };

  return {
    restrict: 'A',
    link: linker
  };
});

The third argument false prevents an unnecessary digest loop.

Demo: http://plnkr.co/edit/9Afq65uatTjnb4J6ICcB?p=preview

If you need to add or remove items dynamically this will work:

app.directive('chosen', function($timeout) {

  var linker = function(scope, element, attr) {

    scope.$watch('countriesList', function() {
      $timeout(function() {
        element.trigger('chosen:updated');
      }, 0, false);
    }, true);

    $timeout(function() {
      element.chosen();
    }, 0, false);
  };

  return {
    restrict: 'A',
    link: linker
  };
});

Demo: http://plnkr.co/edit/rEBu6d3HtaNhThWidB5h?p=preview

Note that by default $watch uses reference equality to determine if to execute the listener or not. If you add an item to the array the variable countriesList will still refer to the same array, so the listener will not execute.

The third argument true passed to $watch makes it use angular.equals instead of reference equality.

本文标签: