Search code examples
angularjsangular-ui-bootstrapangular-uiangular-ui-typeahead

Angular-UI Bootstrap's typeahead ng-model doens't work as expected when placed inside tabs


I'm using angular-ui typeahead plugin as following:

<input type="text" ng-model="selected" uib-typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control">

when I place it inside tabs the following watch expressing stopping to work:

$scope.$watch('selected', function(){
    console.log($scope.selected);
  });

Plunkr with example of my issue is here: http://plnkr.co/edit/65QrdX5DDA9YKenbEUbJ?p=preview

I don't think it's a bug but suspect that <uib-tabset> creates its own scope, but I haven't idea how to solve this issue.

UPDATE1: I've solved this issue by using $parent scope as following:

ng-model="$parent.$parent.selected"

see updated plunkr here: http://plnkr.co/edit/65QrdX5DDA9YKenbEUbJ?p=preview

But it looks for me terrible workaround, is it right to solve this issue in a way I've solved it and if not, what is right way?


Solution

  • A future proof design is always to use the .property in ng-model binding. Like what @Stanelyxu2005 and yourself have already figured out, an isolate scope is being created. By creating a scope variable like this

    JS

    $scope.selected = {city:"" };
    $scope.$watch('selected.city', function(){
    console.log($scope.selected.city);
    });
    

    Markup

    <input type="text" ng-model="selected.city" uib-typeahead="state for state in states | filter:$viewValue | limitTo:8" class="form-control">
    

    will ensure that the prototype chain remains true and is never broken. This will be a better way than using the ugly $parent.$parent workaround. See a link here explaining why using the dot is good practice.