Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

$scope inside and outside ng-include behave differently

so I did some experiment to create a ng-change behaviour on 2 different selectbox while carying the same $scope. one is inside ng-include directive, meanwhile the other one is outside the ng-include directive, the interesting part is though when I implement data-binding it turns out okay, but when I tried to look at my console tab it return differently

the one outside the ng-include directive was okay whereas the one inside the ng-include directive always returns value 'a' or static value

this is the index.html mockup

  <select ng-model="list" ng-change="changeOutsideTemplate()">
    <option value="a">A</option>
    <option value="b">B</option>
  </select>

  {{list}}

  <div ng-include="test"></div> //this scope caries test.html

this is the test.html mockup

<select ng-model="list" ng-change="changeInsideTemplate()">
  <option value="a">A</option>
  <option value="b">B</option>
</select>

{{list}}

this is the controller

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

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.test = "test.html";
  $scope.list = "a";

  $scope.changeInsideTemplate = function() {
    console.log($scope.list); //always returns 'a'
  }

  $scope.changeOutsideTemplate = function() {
    console.log($scope.list); //this is the correct way
  }

});

this is the working example

why do you think the cause of this issue ? anyone care to elaborate ?

like image 240
Eka Rudianto Avatar asked Dec 29 '14 08:12

Eka Rudianto


1 Answers

ng-include directive create a new child scope. here is the DOC

when your model in ng-include html as <select ng-model="list" ng-change="changeInsideTemplate()"> then angular will check for a model list in its child scope, then angular will realize there is no model called list in ng-include child scope. then angular will create a new child scope model called list inside of child scope.

if u do like

<select ng-model="$parent.list" ng-change="changeInsideTemplate()">

then angular will check model list in parent scope. in the parent scope of ng-include scope contains $scope.list which we are concern.

here is the working Plunker


OR you can use like below as @dfsq suggested in the comment.

controller

app.controller('MainCtrl', function($scope) {
  $scope.name = 'World';
  $scope.test = "test.html";
  $scope.list = {value: 'a'};

  $scope.changeInsideTemplate = function() {
    console.log($scope.list.value); //always returns 'a'
  }

  $scope.changeOutsideTemplate = function() {
    console.log($scope.list.value); //this is the correct way
  }
});

index.html

<select ng-model="list.value" ng-change="changeOutsideTemplate()">

test.html

<select ng-model="list.value" ng-change="changeInsideTemplate()">

in test.html angular will check for list.value then angular will know value is a property of a object and there is no object called list with in the child scope. then angular will search the object(list) in parent scope like it will search entire hierarchy.

here is the Plunker


if you have ng-include inside ng-include then second ng-include create a child scope on first ng-include

then in test.html

<div ng-include="$parent.include"></div> // because `$scope.include` in parent scope

and in include.html

<select ng-model="$parent.$parent.list" ng-change="otherChanging()"> // because `$scope.list` is in parent scope of parent scope (second upper parent scope).

here is the Plunker using $parent.

here is the Plunker using Object.

using object more suitable.

like image 85
Kalhan.Toress Avatar answered Sep 20 '22 20:09

Kalhan.Toress