ui-bootstrap angular filter in tab conflict

2019-08-30 18:48发布

问题:

I have an issue with a filter when inside a tabset.

angular.module('myModule', ['ui.bootstrap']);
angular.module('myModule').controller('ModalController', function($scope) {
$scope.favsLib = [1, 19];
$scope.docsLib = [{
    "id": 19
}, {
    "id": 23
}];
$scope.checkboxDoc = false;
$scope.favFilter = function (docsLib) {
    if ($scope.favsLib.length > 0 && $scope.checkboxDoc == true) {
        if ($.inArray(docsLib.id, $scope.favsLib) < 0) return;
    }

    return docsLib;
}
});
angular.module('myModule').directive('tabDirective', function() {
return {
    scope: {
        display: '='
    },
    controller: "ModalController",
    restrict: 'AE',
    replace: true,
    link: function(scope, elm, attrs) {

    }
};


});

here is the html I would like:

<div ng-app="myModule" ng-controller="ModalController">
  <tabset>
    <tab heading="Documents">
      <tab-directive display="docsLib">  <input type="checkbox" ng-model="checkboxDoc">favourites
    <ul>
        <li ng-repeat="doc in docsLib | filter:favFilter">{{doc}}</li>
    </ul>
   </tab-directive>
    </tab>
    </tabset>
</div>

If I take the the input box outside of the tabset the filter works fine:

Working outside tabset - jsfiddle

clicking on checkbox filters results correctly.

But placing the input inside the tabset doesn't work, so there maybe an issue with the ui-bootstrap.

Has anyone any ideas? Thanks.

回答1:

It is no issue about ui-bootstrap, but about scoping.

When placing the checkbox inside the tabstrip, the checkboxDoc property is placed at the inner scope (the scope created by the tabstrip directive). However the property used for filtering your list in placed at the outer scope (the controller scope).

Quick and dirty fix would be to place the checkbox inside the tabstrip, but change the model to ng-model="$parent.checkboxDoc".

The proper way is, to not put a primitive at the scope but an object. So instead of using $scope.checkboxDoc = false, assign $scope.checkboxDoc = {checked: false);. The you can properly read/write the parent/outer/controller scope property by assigning <input type="checkbox" ng-model="checkboxDoc.checked">

See you corrected fiddle: http://jsfiddle.net/xm1q9on9/14/

Somewhere i once read, that the ng-model attribute should always contain at least one dot, like object.property. This mnemonic helps to never assign primitive properties to the scope object directly and would have fixed that probpem. Read more about scoping at the official angular documentation or for even more details at the angularJS Wiki.