I have an Angular app with several nested controllers and views. I implemented infinite scrolling in it closely based on this tutorial for ngInfiniteScrolling: http://binarymuse.github.io/ngInfiniteScroll/demo_async.html
So I have a service that loads items into an array at $scope.content.items
. Then there's an ng-repeat
element that shows each result.
$scope.content = new Content()
$scope.content.loadMore( $scope.currentStream, 2 ) // this part is actually called in the HTML, but while debugging I've just done it in the controller
Now I want to implement search, and instead of making another search page, just have the items load in place of the current list of items. Basically to take the place of $scope.content.items
.
So I built an identical controller, but now calling my search API. I use ng-change
to see if someone has typed in the search box, then within the function that calls, do
$scope.search = function() {
$scope.content = new Search()
$scope.content.load( $scope.query )
}
I can see that this works in the console, that it replaces $scope.content.items
, by doing this in the browser console:
var scope = angular.element($('[ng-controller=HomeController]')).scope()
scope.content.items
That shows me the array of objects I expect in each case (either before triggering ng-change="search()"
or after). But the page itself does not update. It just shows the stuff from the Content()
service.
Likewise, if I replace the above two lines from my controller with these below, it shows the content from the Search()
service:
$scope.content = new Search()
$scope.content.load( 'thom' )
Long story short, I feel like the services and API work, but the page is not updating when I change the $scope.content.items
array used by ng-repeat
.
Here is the HTML
<div class="panel panel-item" ng-repeat="item in content.items" ng-hide="hideItem">
<h2 ng-hide=" item.stream == 'read' " data-ng-bind="item.title"></h2>
<a ng-click="openReaderModal( item )" class="cursor-pointer" ng-show=" item.stream == 'read' ">
<h2 data-ng-bind="item.title"></h2>
</a>
// ...
<div class="clearfix"></div>
</div>
Fixed it, somehow. Here is my routes from app.config()
before:
$stateProvider
// ...
.state( 'app', {
url: '/app',
templateUrl: 'app/views/app.html',
controller: 'HomeController'
})
.state( 'app.home', {
url: '/main',
templateUrl: 'app/views/home.html',
controller: 'HomeController'
})
.state( 'app.profile', {
url: '/profile',
templateUrl: 'app/views/profile.html',
controller: 'ProfileController'
})
.state( 'app.read', {
url: '/read',
templateUrl: 'app/views/stream-content.html',
controller: 'HomeController'
})
.state( 'app.watch', {
url: '/watch',
templateUrl: 'app/views/stream-content.html',
controller: 'HomeController'
})
.state( 'app.listen', {
url: '/listen',
templateUrl: 'app/views/stream-content.html',
controller: 'HomeController'
})
And here's after:
$stateProvider
// ...
.state( 'app', {
url: '/app',
templateUrl: 'app/views/app.html',
controller: 'HomeController'
})
.state( 'app.home', {
url: '/main',
templateUrl: 'app/views/home.html'
})
.state( 'app.profile', {
url: '/profile',
templateUrl: 'app/views/profile.html',
controller: 'ProfileController'
})
.state( 'app.read', {
url: '/read',
templateUrl: 'app/views/stream-content.html'
})
.state( 'app.watch', {
url: '/watch',
templateUrl: 'app/views/stream-content.html'
})
.state( 'app.listen', {
url: '/listen',
templateUrl: 'app/views/stream-content.html'
})
And it works. If anyone can provide an explanation, I'll credit them the answer.
The routing in angular works like this.
When we provide a controller for the $stateProvider its actually considered as a new constructor (new keyword as in java) thus the data is re-initiated to defaults. The new constructor will be the child to itself, to access the parent controller one can use the $parent