0

In my App I have an $http.get() request that stores data into the array $scope.requirements and a boolean into $scope.requirementsFulfilled.

I have a directive using the same controller as the page. They both do an ng-repeat on the $scope.requirements. When the requirementsFulfilled is false only the directive version shows, when true only the containing page.

The problem is when I envoke $http.get() after the first time the results are only being stored in the directive version. How do I make sure this information is bound to both?

Within the controller...

$scope.requirementsFulfilled; 
$scope.requirements = [];

$scope.getRequirements = function(url) {
  $http.get(url)
    .then(function(res){
      $scope.requirements = res.data.requirements;   
      $scope.setFulfilled( res.data.fulfilled );              
    });  
  };

$scope.submitRequirementScan = function() {
  if ($scope.checkRequirement() ) {
      $scope.getRequirements('tempjson/requiredPartsFulfilled.json');
     }
  };

$scope.setFulfilled = function( inputFulfilled ) {
   $scope.requirementsFulfilled = inputFulfilled;
  };

$scope.getRequirements('tempjson/requiredParts.json');

The page gets the requirements and populates the page. Then the user takes actions which fires off checkRequirement() and then fetches the new json if true. From this point only the directive is updating.

I believe that a child scope is being created for the directive, but I am not certain exactly what is happening. Here is the entirity of the directive info.

.directive("operationRequirements", function () {
return {
    restrict: "E",
    templateUrl: "requirements/requirements.html"
    };
});

What is going on with it?

edit - Html for the directive

<div class="col-md-6 col-md-offset-3">
    <h5>Scan Requirements</h5>
    <form ng-submit="submitRequirementScan()" ng-controller="operationCtrl">
       <label> <div class="glyphicon glyphicon-barcode ng-hide" ng-hide="requirement.scanned"></div>
      <input type="text" ng-model="text" name="text" placeholder="Scan Barcode" autofocus /></label>
      <input type="submit" id="submit" value="Submit Scan" class="btn" />
    <table class="table table-hover">
       <tr ng-repeat="requirement in requirements | filter : unScannedFilter">
            <td>{{$index + 1 }}</td>
            <td>
                <div class="glyphicon glyphicon-barcode ng-hide" ng-hide="requirement.scanned"></div>
                <div class="glyphicon glyphicon-check ng-show" ng-show="requirement.scanned"></div>{{requirement.scanned}}     
                <div class="col-md-4">
                    <input type="checkbox" ng-model="requirement.scanned">
                </div>
            </td>
            <td>{{requirement.partId}} - {{requirement.partDescription}}</td>
        </tr>
    </table>
   </form>
 </div>

edit 2 -- Html that invokes the directive operation-Requirements and the on page display of the requirements hidden with ng-show.

<div class="row" ng-hide="requirementsFulfilled" >
    <operation-Requirements></operation-Requirements>
</div>
<div class="col-md-12" ng-show="requirementsFulfilled">
       <table class="table table-hover">
            <tr ng-repeat="requirement in requirements">
                <td>{{$index + 1 }}</td>
                <td>
                    <div class="glyphicon glyphicon-barcode ng-hide" ng-hide="requirement.scanned"></div>
                    <div class="glyphicon glyphicon-check ng-show" ng-show="requirement.scanned"></div>
                </td>
                <td>{{requirement.partId}} - {{requirement.partDescription}}</td>
            </tr>
        </table>
</div>
Todd
  • 3
  • 4
  • What does your HTML look like? – Stephen Gilboy Apr 13 '16 at 18:58
  • I have added the html for both the containing page and the directive. – Todd Apr 13 '16 at 19:15
  • Where's the html for the directive on the page? – Hoyen Apr 13 '16 at 19:24
  • @Todd And how come your directive doesn't declare the scope variables? – Hoyen Apr 13 '16 at 19:27
  • @Hoyen It looks like he'll want to go with a "Parts" service which would have the the requirements & fulfilled variables. That way its available to both. – Stephen Gilboy Apr 13 '16 at 19:30
  • Are you assuming that updating the `$scope` in one place updates it in the other? Due to prototypical inheritance of scopes, I suspect that is not happening. Try putting breakpoints in your controller and see if `$scope.$id` is the same in both. – Jack A. Apr 13 '16 at 19:30
  • @Hoyen I have updated the question to include the operationRequirements directive piece. – Todd Apr 13 '16 at 19:54
  • Try this: In the directive add 'scope: false'. And in the directive's html remove ng-controller="operationCtrl". Basically you are creating a new instance of the controller in the directive that is separate from the parent. When you set scope to false, it will share the same scope as the parent. – Hoyen Apr 13 '16 at 19:55
  • Here's a good explanation for it in the accepted answer: http://stackoverflow.com/questions/17900201/how-to-access-parent-scope-from-within-a-custom-directive-with-own-scope-in-an – Hoyen Apr 13 '16 at 19:57
  • Thank you all for your comments and suggestions. The suggestion from @Hoyen to add `'scope:false'` and remove `ng-controller` did in fact solve the issue. As for setting up a service, is this something I should still proceed with for cleaner code or 'best practice'? – Todd Apr 18 '16 at 20:30

1 Answers1

0

So maybe this will help point you in the right direction. What I've done is pulled out the requirements stuff into its own service. Now you have a singleton that handles everything that deals with parts. When its updated in one place its updated everywhere. The directive no longer needs that other controller.

http://plnkr.co/edit/Nej79OI3NrKcrkMNix3D?p=preview

app.service('partsService', function() {
  return {
requirementsFulfilled: false,
requirements: [],
getRequirements: function () {
  this.requirements.push({partId: 1, partDescription: 'Some Desc', scanned: false});
  this.requirements.push({partId: 2, partDescription: 'Some Desc 2', scanned: true});
},
submitScan: function (id) {
  this.requirements.filter(function (part) {
    return part.partId === id;
  }).map(function (part) {
    part.scanned = true;
  });

  this.requirementsFulfilled = this.requirements.filter(function (part) {         return !part.scanned }).length === 0;
    }
  };
 });
Stephen Gilboy
  • 5,572
  • 2
  • 30
  • 36