Weston Sazehn
Weston Sazehn

Reputation: 33

Angular.js no scope in ng-include html template

I am learning as I go with my first Angular project and have ran into an issue.

Goal: When an link is clicked in a given .html template placed in with ng-include, I want it to change the value of $scope.selectedLocation

The issue: The value of $scope.selectedLocation does not change.

I read that the ng-include creates a child scope, so in order to change the parent scope variable, you could place $parent in front of the value. I have tried this and it does not work.

Main index page:

<body ng-app="photoApp" id="bodyDiv" >
    <div ng-controller="PhotoGallery">
        <div>
        <ng-switch on="selectedLocation" >
            <div ng-switch-when="home" >
                <div ng-include="'home.html'"></div>
            </div>
            <div ng-switch-when="loc1">
                <div ng-include="'file1.html'"></div>
            </div>
            <div ng-switch-when="loc2">
                <div ng-include="'file2.html'"></div>
            </div>
        </ng-switch>
        </div>
    </div>
</body>

home.html code:

<div class="container-fluid">
    <div class="row">
        <div class="col-lg-6 col-md-6 col-sm-6">
            <a href="#" ng-click="selectedLocation='loc1'">
                Location 1
            </a>
        </div>
        <div class="col-lg-6 col-md-6 col-sm-6">
            <a href="#" ng-click="selectedLocation='loc2'">
                Location 2
            </a>
        </div>
    </div>
</div>

photoApp.js code:

var photoApp= angular.module('photoApp', []);

westonPhotographyApp.controller('PhotoGallery', function($scope)
{

    $scope.selectedLocation ="home";
}

Upvotes: 1

Views: 504

Answers (2)

JanS
JanS

Reputation: 2075

You seem to have misnamed your app variable. Either name westonPhotographyApp photoApp or vice-versa:

var photoApp = angular.module('photoApp', []);

photoApp.controller('PhotoGallery', function($scope) {
      $scope.selectedLocation ="home";
}

Anyways, you could improve on your design: You could use controllerAs syntax. It names your controller and makes it accessible throughout descendant scopes:

Index:

<div ng-controller="PhotoGallery as pgCtrl">
  <div>
    <ng-switch on="selectedLocation" >
      <div ng-switch-when="home" >
        <div ng-include="'home.html'"></div>
        ...

Home:

<div class="container-fluid">
    <div class="row">
        <div class="col-lg-6 col-md-6 col-sm-6">
            <a href="#" ng-click="pgCtrl.selectedLocation='loc1'">
                Location 1
            </a>
        </div>
        <div class="col-lg-6 col-md-6 col-sm-6">
            <a href="#" ng-click="pgCtrl.selectedLocation='loc2'">
                Location 2
            </a>
        </div>
    </div>
</div>

With your controller:

photoApp.controller('PhotoGallery', function() {
    var vm = this;

    vm.selectedLocation ="home";
}

Upvotes: 0

Matt Oakley
Matt Oakley

Reputation: 96

The issue is that you're binding to a primitive in an inherited scope. To fix it you should pass an object:

westonPhotographyApp.controller('PhotoGallery', function($scope)
{
   $scope.vm = {
     selectedLocation: "home"
   }
}

Html

<div class="container-fluid">
<div class="row">
    <div class="col-lg-6 col-md-6 col-sm-6">
        <a href="#" ng-click="vm.selectedLocation='loc1'">
            Location 1
        </a>
    </div>
    <div class="col-lg-6 col-md-6 col-sm-6">
        <a href="#" ng-click="vm.selectedLocation='loc2'">
            Location 2
        </a>
    </div>
</div>

ng-include creates a new scope that inherits the parent (controller) scope through the prototype chain. In javascript you can't replace the value of the shadowed inherited property. Passing an object works as you're changing a property on a pointer to the object.

https://github.com/angular/angular.js/wiki/Understanding-Scopes

Upvotes: 1

Related Questions