1

I'm writing an app that uses the same table with the same data in multiple places. I created a custom directive that allows me to reuse this table. Unfortunately, if I edit the table in one instance, the other instance does not refresh. How do I link these two so that any edits I make to one show up in the other?

2
  • How are you passing the table data to the directive? Commented Mar 2, 2015 at 17:44
  • I have a service that makes an AJAX call to my Django REST backend. The app is a media management app that has Image and Video tabs, as well as a slideshow tab. The Image and Video tabs have their own tables that are duplicated in the Slideshow tab since users can create slideshows with existing media. I think the problem is that the Slideshow instances of these tables are nested in the slideshow controller. If I make a test tab that uses the directive, it stays in sync with the main image tab, but the Slideshow instance doesn't. Commented Mar 2, 2015 at 17:53

1 Answer 1

2

It sounds like you've mostly figured it out, the hard part is getting your data into a shape where the videos and photos can be shared by the slide show. I recommend doing this in a shared data access object returned by a separate factory in Angular, rather than directly in a scope. I've got a sample in Plunkr if it helps.

The sample has a directives that binds to shared data, retrieved from a factory as an object injected into two separate scopes. In your case, you would have to add methods to retrieve data from the server, and shape it for display.

testApp.factory("News", [function () {
  var news = {
    "stories": [
      {"date": new Date("2015-03-01"), "title": "Stuff happened"}, 
      {"date": new Date("2015-02-28"), "title": "Bad weather coming"},
      {"date": new Date("2015-02-27"), "title": "Dog bites man"}
    ],
    "addStory": function (title) {
      var story = {
        "date": new Date(),
        "title": title
      };
      news.stories.push(story);
    }
  };
  return news;
}]);

Both controllers reference the same factory for the data:

testApp.controller("FirstController", 
  ["$scope", "News", function ($scope, news) {
    $scope.news = news;
}]);

testApp.controller("SecondController", 
  ["$scope", "News", function ($scope, news) {
    $scope.news = news;
}]);

Views then pass the data into to the news list directive, which both shares the data and keeps the directive relatively dumb.

  <div ng-controller="FirstController">
    <news-list news="news" title="'First List'"></news-list>
  </div>
  <div ng-controller="SecondController">
    <news-list news="news" title="'Second List'"></news-list>
  </div>

The news-list directive is just dumb formatting in this example:

testApp.directive("newsList", 
  function() {
    var directive = {
      "restrict": "E",
      "replace": false,
      "templateUrl": "news-list.html",
      "scope": {
        "news": "=news",
        "title": "=title"
      } 
    };
    return directive;
});

View template:

<div class="news-list">
  <p>{{title}}</p>
  <ul>
    <li ng-repeat="story in news.stories | orderBy:'date':true">{{story.date | date:'short'}}: {{story.title}}</li>
  </ul>
  <form>
    <input type="text" id="newTitle" ng-model="newTitle" />
    <button ng-click="news.addStory(newTitle)">Add</button>
  </form>
</div>
Sign up to request clarification or add additional context in comments.

6 Comments

Thank you so much for taking the time to add all this! I've got a very similar setup going on, though I'm using a service instead of a factory, not sure if that makes a difference. When I set it up like this, two unnested controllers, everything works perfectly. The problem I run into is when I have one tab that's just governed by the image controller, and then the other which is governed by the image controller, but nested in a tab governed by the slideshow controller. To visualize the hierarchy: Tab 1: Image controller Tab 2: Slideshow Controller > Subtabs -> Image controller.
Do you pass the same data object to both directives? If the controllers are nested, it should be just as easy. The important thing is that the directives use the same data, not separate-but-equal data loaded from two different controllers.
I think that may be it. I'm absolutely attempting to do that, but not sure I'm succeeding. The slideshow and the image controllers take the image service, and both set $scope.imageList to the result of the getImages function within the service. I've tried not calling the getImage function from the slideshow controller, but it didn't seem to change anything. They initially load the same data, but I think that it IS two separate but equal data objects. In the context of the example you gave above, how would the same idea come into play? And does using a factory over a service change anything?
What if the child scope didn't overwrite imageList, but just used the imageList set by the parent scope? That way you can be sure it is the same.
Would not setting the imageList in the SlideshowController be an equivalent action? I've tried only setting it in the ImageController, but it hasn't helped. Though they're both getting their data from the Images service, they just don't update if an edit is made to either. It seems like the initial get call in each is creating two separate but identical datasets. I don't understand why this happens when one instance is nested, but works correctly when they're both at the same level since SlideshowController doesn't touch the data.
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.