0

I have a page which uses two controllers, SearchController and ProductController, that are both part of one app. They both sit on the main page, and are called using ng-controller. I have a route set up for when i click 'search' and this loads an ng-view which uses the ProductController. This loads up fine, but the problem I'm having is that the div with ProductController already on the page doesn't get affected when search is clicked.

Here is the plunker: http://plnkr.co/edit/LnsL0M3KczBmeKsS9uDb?p=preview

HTML - I have a dummy select box. The important part here is the second div with ProductController. This is meant to show up if $scope.products.length > 0. When search is clicked, $scope.products inside of ProductController is filled, but this box isn't affected.

<div ng-controller="SearchController" class="ng-cloak">
  <div class="search-form">
    <select ng-model="search.category">
      ...
    </select>
    <button class="btn btn-primary" ng-disabled="search.category == 0" ng-click="doSearch()">Search</button>
  </div>
</div>

<div ng-controller="ProductController" class="ng-cloak">
  <div class="criteria" ng-show="products.length > 0">
    <div>Category: {{search.category}}</div>
  </div>
</div>

<div ng-view></div>

Inside my ProductController i load a products.json file that just brings back everything. So I would think that now that $scope.products.length > 0, the above div should show. But it doesn't. What am I doing wrong?

  $http.get('products.json')
    .success(function(data) {
      $scope.products = data[0].products;
      sessionService.loadProducts(data[0].products);
      console.log('JSON LOADED-------------');
      console.log('products.length: ', $scope.products.length);
    });

I'm using console.logs so you can follow what's happening a little better.

Also, once you click search. If you click search again, it doesn't run anything. I'm assuming this is because it's already ran the location.path function. But why does this happen and how can I make it search again?

mnsr
  • 12,337
  • 4
  • 53
  • 79

1 Answers1

0

So a couple of things leap out. First, in your controllers.js, you're specifying what to inject using both $inject and the second argument (the array) you are passing to app.controller. This is not right - you should have one or the other. In getting your plunkr to work, I removed the two $injects at the bottom.

Second, the main problem you have is scoping. By passing in $rootScope to both controllers (I passed them in as the first array argument right before '$scope') and adding $rootScope as the corresponding first argument, both controllers can now "talk" through $rootScope.

Then:

  1. $rootScope.search instead of $scope.search
  2. $rootScope.products instead of $scope.products

Does this help? Here's the plunkr with these changes made

Ram Rajamony
  • 1,717
  • 15
  • 17
  • ahh that's interesting. I didn't think to use $rootScope. That makes my 'sessionService' pointless. When you say 'you should have one or the other', what do you mean exactly? Also, there's a part of my question you may have missed down the bottom of the page.. its' about submitting the form after the $location has changed. – mnsr May 24 '13 at 03:43
  • The controller ProductController is run only when the location CHANGES to /search. When you are on /search and you remain on it, your ProductController is not rerun. Some thought is required on how you want to handle this ... With regards to doing one of the other, I meant that you should either use searchController.$inject OR the expanded args to app.controller ('SearchController', [...], function(){}). Did you see the plunkr I forked off yours? You should be able to see it there. – Ram Rajamony May 24 '13 at 04:10