Jess
Jess

Reputation: 25029

Angular filter does not work

I ran into this problem with an angular js project that was started with the angular-seed project. Here's the code snip:

Search: <input ng-model="searchText" placeholder="Type in a full text search">
<p ng-controller="MyCtrl1">
Search: <input ng-model="searchText">
Showing {{searchText}}.
<ol>
    <li ng-repeat="phone in phones | filter:searchText">
    {{phone.name}} ha {{phone.snippet}}</li>
</ol>
</p>

The first search box works! The second does NOT! I don't get any errors to indicate what is wrong.

When I remove the ng-controller="MyCtrl1" markup, both search boxes work! The tutorial, angular-phonecat, and angular-seed projects are a little different. The seed project uses this kind of code to assign the controller to the view.

// Declare app level module which depends on filters, and services
angular.module('myApp', ['myApp.filters', 'myApp.services', 'myApp.directives', 'myApp.controllers']).
  config(['$routeProvider', function($routeProvider) {
    $routeProvider.when('/view1', {templateUrl: 'partials/partial1.html', controller: 'MyCtrl1'});
    $routeProvider.when('/view2', {templateUrl: 'partials/partial2.html', controller: 'MyCtrl2'});
    $routeProvider.otherwise({redirectTo: '/view1'});
  }]);

The phonecat project uses the ng-controller="MyCtrl1" markup. Obviously I don't need to declare my controller twice, so it makes sense for me to remove it.

This fixes the problem, but why is this happening?

(Also I wanted to put this information into SO in case anyone else runs into this issue)

Upvotes: 1

Views: 2493

Answers (2)

hawk
hawk

Reputation: 5408

ng-controller="MyCtrl1" has own scope. According to documentation The ngController directive assigns behavior to a scope. This is a key aspect of how angular supports the principles behind the Model-View-Controller design pattern. And second, Angular has lazy binding nature, you will not see the error.

Upvotes: 2

zs2020
zs2020

Reputation: 54504

In AngularJS, each controller creates a new scope. So you need to use $parent to access the model defined at the outer controller if you have nested controllers:

<div ng-app ng-controller="MyCtrl1">Search:
    <input ng-model="searchText" placeholder="Type in a full text search">
    <p ng-controller="MyCtrl1">Search:
        <input ng-model="$parent.searchText">Showing {{searchText}}.
        <ol>
            <li ng-repeat="phone in phones | filter:searchText">{{phone.name}} ha {{phone.snippet}}</li>
        </ol>
    </p>
</div>

Upvotes: 6

Related Questions