1

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";
}

2 Answers 2

1

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

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

Comments

0

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";
}

1 Comment

Using the 'controller as' syntax did the trick! I learned a lot from this, thank you!

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.