Apply Angular Template to Template
So, I'm not sure what I'm asking, but I want to achieve this:
Index.html:
<div ng-view>
</div>
<script>
angular.module('myApp', ['ngRoute'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', { controller: "HomeController", templateUrl: '/Partials/Home/Dashboard.html' });
$routeProvider.otherwise({ redirectTo: '/' });
}]);
</script>
Home / Dashboard.html:
<h2 class="page-header">{{welcome}}</h2>
<!-- Insert my reusable component here -->
My reusable component will be in MyComponent/Component.html
and associated with a controller myApp.component.controller
.
So I want me to drop the Resuable component into the page and bind it to my controller. So I got, as far as possible:
.directive('MyComponent', function() {
return {
restrict: 'E',
scope: {
},
templateUrl: '/MyComponent/Component.html'
};
});
So how do I now bind a controller to it? I'm doing it:
.directive('MyComponent', function() {
return {
restrict: 'E',
resolve: function () {
return /* resolve myApp.component.controller */;
},
templateUrl: '/MyComponent/Component.html'
};
});
source to share
So I just want to clarify a few things here.
/MyComponent/Component.html:
<h2>{{welcome}}</h2>
/mycomponent.directive.js:
.directive('MyComponent', function() {
return {
restrict: 'E',
controller : 'ComponentController',
templateUrl: '/MyComponent/Component.html'
};
});
the above link is like this in index.html:
<h2>{{welcome}}</h2> <!-- this is from ng-controller = HomeController -->
<my-component></my-component> <!-- this is scoping from ng-controller = ComponentController -->
This leads to the result
<h2>Hello from MyComponent</h2>
<h2>Hello from MyComponent</h2>
It looks like it ComponentController
took over the whole area. Then I changed the directive to this:
.directive('MyComponent', function() {
return {
restrict: 'E',
// controller : 'ComponentController',
templateUrl: '/MyComponent/Component.html'
};
});
And changed index.html to this:
<h2>{{welcome}}</h2> <!-- this is from ng-controller = HomeController -->
<div ng-controller="ComponentController">
<my-component></my-component> <!-- this is scoping from ng-controller = ComponentController -->
</div>
This gave the correct result:
<h2>Welcome from HomeController</h2>
<h2>Welcome from ComponentController</h2>
Then I changed this directive again:
.directive('MyComponent', function() {
return {
restrict: 'A', // <----- note this small change, restrict to attributes
// controller : 'ComponentController',
templateUrl: '/MyComponent/Component.html'
};
});
I changed index.html to this:
<h2>{{welcome}}</h2>
<div ng-controller="ComponentController" my-component></div>
And it also produced the desired result, only in fewer lines of code.
So I just hope this simplifies the directives for people a little better. I put this to completeness and the steps I took to achieve this. Obviously I got some help from other answers that pointed me in the right direction.
source to share
When a directive requires a controller, it receives that controller as the fourth argument to its link.
.directive('MyComponent', function() {
return {
restrict: 'E',
controller: 'MyController', // attach it.
require: ['MyController','^ngModel'], // required in link function
templateUrl: '/MyComponent/Component.html',
link: function(scope, element, attrs, controllers) {
var MyController = controllers[0];
var ngModelCtlr = controllers[1];
///...
}
};
});
The ^ prefix means that this directive looks for a controller on its parents (without the ^ prefix, the directive will search for a controller only for its own element).
Best Practice: Use a controller if you want to expose the API to other directives. Otherwise, use the link.
source to share