Search code examples
javascriptangularjsencapsulation

How do you encapsulate setting a $scope value across multiple controllers?


It's my first Angular project and I have multiple pages with view code that looks like this:

<!-- in myapp.com/kitties -->
<tr ng-repeat="row in kitties">
    <td>{{row.fuzziness}}</td>
    <td>{{row.meowLevels}}</td>
    <td>{{row.evilness}}</td>
    <td>{{row.redDotProgress}}</td>
</tr>

<!-- in myapp.com/princesses -->
<tr ng-repeat="row in princesses">
    <td>{{row.magic}}</td>
    <td>{{row.woodlandCreatureCount}}</td>
</tr>

<!-- in myapp.com/fairies-->
<tr ng-repeat="row in fairies">
    <td>{{row.friendship}}</td>
    <td>{{row.mischief}}</td>
    <td>{{row.wingColour}}</td>
</tr>

I'm trying to encapsulate out the behaviour of checking the backend API for the table data, checking local storage for the table data, and then putting that data into $scope.kitties, $scope.princesses or $scope.fairies. Each page has their own controller and I don't want to put that repeated code in each page's controller. Where can I put this encapsulated code? I tried a service, but I can't access $scope from the service. I don't think a directive works because I only want to set one value in the $scope.


Solution

  • 1. A service it's one of the good ways to do it, but you don't need to access $scope from it. Look below at this example:

    app.factory('generalService', function($timeout,$http,$q,$location){
    
      var kitties= getYourKittiesFunction();
    
      var service={
         kitties:kitties
      };
      return service;
    });
    
    
    app.controller('yourController', function($scope,generalService{
      // you have generalService.kitties now
    })
    

    So, I've declared a service, where I get my data and I send this service as a reference to controllers, where I can use it by calling .custom-property

    2. Another way it's to have a mainController in your master page. Declare there everything you want and it will be visible from every child controller across the application ( because of inheritance )

    Example :

    <div ng-controller="parentController">
        <h1>{{text}}</h1>
        <div ng-controller="childController">
            <h1>{{text}}</h1>
        </div>
    </div>
    
    app.controller("parentController", [ '$scope', function($scope){
        $scope.text= "Hello world";
     }]);
    
    app.controller("childController", [ '$scope', function($scope){
        // $scope.text is visible from parentController
    }]);
    

    UPDATE: I think I didn't understand well first time I read it and what you really want is to encapsulate your view code into something to share it across multiple pages

    In order to do that follow these steps:

    a. In order to do that create a controller called, for example, magicalListController, where you'll put your code to fill your arrays ( kitties, fairies and princesses )

    b. Put that html code in a separate view

    c. Include it in your pages

    Example:

    app.controller('magicalListController', function($scope){
      $scope.kitties=// get your kitties
      $scope.fairies= // get your fairies
      $scope.princesses= // get your princesses
    });
    
       // View code it's exactly how you posted in 
    

    And insert into another view

     <div ng-include="'path to your view'" ng-controller="magicalListController"></div>