1

I have been following several examples here, but am not seeing the same results. I have two controllers one for a dropdown and one for a table. When a user selects an item from the drop down a factory kicks off and runs a get. The intent is to have it update the table data source. The get runs and successfully updates the IB variable. However, the table source does not update. Bellow is my html and js

App.js: https://gist.github.com/fce53552ebc0ca8cdae68511a7cedc38 index.html: https://gist.github.com/3077b367bdf16e3e18e603fb93f37729

Any help as to what I am doing wrong would be much appreciated ;)

3
  • Perhaps your should try to read a bit more about AngularJs. Because you mix the use auf services once in your controller and then in a factory, the best is to create one or more central services to implemt your http service calls. And I think you don't need two controller for this Problem or is this just a simple example for a bigger problem you try to solve? Commented Apr 3, 2016 at 20:42
  • I am refactoring my working piece which is one controller that I want to extend. The controller started to get a bit unwieldy so I thought I would break out the pieces (adding some modals and other things to this). This is also meant to be a learning exercise for me, I always need to go back and read, that is for sure. I will read up some more Thanks! Commented Apr 3, 2016 at 21:41
  • This is a common pattern and a good time for you to use of directives. One for each of your UI elements--dropdown and table--where each directive has it's own controller. I'll slap together a plunker and post it with instructions in the next hour. Commented Apr 3, 2016 at 22:01

2 Answers 2

1

My guess is you want to only use one controller if you want to share data between them. Here's a working demo (for some reason it will not work in a fiddle although it works in my browser).

index.html

<!DOCTYPE html>
<html>
  <head>
    <script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.5.0/angular.min.js"></script>
    <script src="ctrl.js"></script>
  </head>
  <body>
    <div ng-app="app" ng-controller="moviesCtrl">
      <h1>Movies By My Favorite Directors</h1>
      <select ng-model="director">
        <option ng-repeat="director in directors" value="{{ director.id }}">{{ director.name }}</option>
      </select>
      <table>
        <tr>
          <td>Movie Title</td>
          <td>Lead Actor</td>
        </tr>
        <tr ng-repeat="film in movies[director].films">
          <td>{{ film.title }}</td>
          <td>{{ film.lead }}</td>
        </tr>
      </table>
    </div>
  </body>
</html>

ctrl.js

angular.module('app', []).controller('moviesCtrl', function($scope) {
  $scope.directors = [
    {
      id: 0,
      name: "Stanley Kubrick"
    },
    {
      id: 1,
      name: "Quentin Tarantino"
    }
  ];
  $scope.movies = [
    {
      directorId: 0,
      films: [
        {
          title: "The Shining",
          lead: "Jack Nicholson"
        },
        {
          title: "A Clockwork Orange",
          lead: "Malcolm McDowell"
        },
        {
          title: "2001: A Space Odyssey",
          lead: "Keir Dullea"
        }
      ]
    },
    {
      directorId: 1,
      films: [
        {
          title: "Pulp Fiction",
          lead: "John Travolta"
        },
        {
          title: "Inglorious Buddies",
          lead: "Brad Pitt"
        },
        {
          title: "Django Unchained",
          lead: "Jamie Foxx"
        }
      ]
    },
  ];
});

Note: The directorId field serves as a sort of comment for understanding which director corresponds to which movies. It has no value in the code.

Sign up to request clarification or add additional context in comments.

Comments

1

(plunkr)

So this is probably more than you asked for, but given this is a common theme, especially for beginners, I thought I'd offer a simplified response (one of many variations). I do not intend to make this is a long winded tutorial but rather only a summary. The intention is to point you in the right direction and urge you go at it independently. The solution focuses on using Angular directives, a powerful pattern offered in Angular 1.X (further evolved in AJS 2.X). In this example I have 2 directives 'cf-get-data-button' and 'cf-show-data', where the former acts like your drop-down selection (getData()) and the latter acts as your table where its contents get updated as a result (simulated as latest UTC time). I have also used two more important patterns: 1. a 'factory' pattern where a singleton service is implemented and where your ajax API reside and 'injected' into the directives and thus made available to them and 2. async promises returned from ajax calls, both of which you indirectly touch on in your question. I won't go into the details for those either, so you can ignore for now, but I suggest you visit these if you haven't done so already. Note, in this example, the result of the simulated AJAX call ($timeout) is available only after the promise is returned.

At the end, you need one outer controller for your 'page' normally in keeping with AJS' quasi MVC world-view. However, each directive provides its own 'controller' which aligns with the componentization and separation of concerns you are looking for. The service (as a singleton) serves as the 'lynchpin' for the data, and as such, since both directives have access to it (via injection), they can request and/or consume that data, i.e. the simulated dropdown directive asks for data and the simulated table directive displays it (again,UTC time is shown). Note, directives can be customized in various ways and the ones I've included are some of the simplest.

You can start with index.html (below--note the 2 directives inside the body and the linked js scripts) and take it from there. I have added comments inside the js and html files, BTW. Feel free to ask if you have questions.

<!DOCTYPE html>
<html ng-app="Tutorial">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <script data-require="[email protected]" src="https://code.angularjs.org/1.4.9/angular.js" data-semver="1.4.9"></script>

    <script src=app.js></script>  
    <script src=mock_ajax_service.js></script>
    <script src=getdatabuttondirective.js></script>  
    <script src=showdatadirective.js></script>
  </head>

  <body ng-controller="TutorialController">
    <p>One UI directive triggers update on another UI directive</p>

    <cf-get-data-button></cf-get-data-button>
    <br>
    <cf-show-data></cf-show-data>
  </body>

</html>

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.