2

I am having a problem in AngularJs when using ng-include to include an html template that has its own controller.

The problem in short is that I am able access scope variables defined in the controller of the included template in the template itself but can't do the opposite (accessing a model defined in the template inside its controller).

This is my index.html page at which I include test.html template:

<html ng-app="myApp">
<head>
  <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script>
  <script src="app.js"></script>

  <body>
    <div ng-controller="TestController" ng-include="'test.html'"></div>
  </body>
</html>

Here is the test.html template:

<div>
{{foo}}
<br />
<input type="text" ng-model="username" />{{username}}
<br />
<button ng-click="go()">Click here</button>
</div>

And finally this is my controller:

myApp.controller('TestController', function($scope) {
  $scope.foo = 'Hello World';
  $scope.go = function() {
    console.log('Username = ' + $scope.username);
  }
});

With no problem I can do the following:

  • Accessing foo that is defined in the controller in the template
  • Accessing username that is defined in the template in the template itself

But I can't do the following

  • Accessing username that is defined in the template in the controller (the output is undefined in the go() function)

Here is a plunker.

Thanks in advance.

  • possible duplicate of [AngularJS: dot in ng-model](http://stackoverflow.com/questions/17606936/angularjs-dot-in-ng-model) – charlietfl May 20 '15 at 00:21
  • I've read this one already and I think my case is different. I did try to use **info.username** as a name for the model instead but it didn't work either. – Ahmed Abdullah Hussein May 20 '15 at 00:32

2 Answers2

1

Its because ng-include directive creates new scope always when it is included,

instead of declaring your controller in

<div ng-controller="TestController" ng-include="'test.html'"></div>

declare it in test.html itself,

<div ng-controller="TestController">
 {{foo}} <br />
 <input type="text" ng-model="username"/>    {{username}}     <br />
 <button ng-click="go()">Click here</button>
</div>

Hope this helps!

Alhuck
  • 1,029
  • 8
  • 11
  • What is the problem with creating a new scope? I mean why do I face the above problem (accessing the scope in the view but not vice versa) – Ahmed Abdullah Hussein May 20 '15 at 10:16
  • Its because `ng-include` creates a new child scope, which is inherited from TestController scope or its parent scope and this child scope is not accessible to parent scope. – Alhuck May 20 '15 at 10:44
  • Ah I see! First `ng-controller` runs ([priority 500](https://docs.angularjs.org/api/ng/directive/ngController)), creating a new scope, *then* `ng-include` runs ([priority 400](https://docs.angularjs.org/api/ng/directive/ngInclude)), creating yet another child scope. And the controller only has access to the parent scope. Brilliant! – Claudiu Nov 18 '15 at 21:04
0

Ok what i suggest you to do is alias your controller and inser the model in its scope.

Alias your controller:

<div ng-controller="TestController as testCtrl" ng-include="'test.html'"></div>

Actually this code is allowing you to use testCtrl to prefix your variables and isert them in your scope.

Inser the model in the controller scope:
So now you can insert your model in the scope.

<input type="text" ng-model="testCtrl.username" />{{testCtrl.username}}

So now in your controller you can access to that variable like that:

$scope.testCtrl.username
borracciaBlu
  • 4,017
  • 3
  • 33
  • 41