[AngularJS] Reusable directive, require from parent controller
Glorious Directives for Our Navigation
NoteWrangler navigation has now been broken into two parts: the children — nw-nav-item
— and the parent — nw-nav
.
Help the children and parent communicate by using what we have learned about $scope
and link
. They'll need to function as a nav should when clicked.
Create a default activeNav
variable on nwNav
's $scope
and make it default to'Notes'
.
angular.module('NoteWrangler') .directive('nwNav', function() { return { restrict: 'E', controller: function($scope) { $scope.activeNav = 'Notes'; } }; });
Create a function called getActiveNav
in the controller of the nw-nav
directive that returns the value of $scope.activeNav
variable.
angular.module('NoteWrangler') .directive('nwNav', function() { return { restrict: 'E', controller: function($scope) { $scope.activeNav = 'Notes'; this.getActiveNav= function(){ return $scope.activeNav; }; } }; });
Create a function called setActiveNav
on the controller of the nw-nav
directive that sets the value of $scope.activeNav
variable.
angular.module('NoteWrangler') .directive('nwNav', function() { return { restrict: 'E', controller: function($scope) { $scope.activeNav = 'Notes'; this.getActiveNav= function(){ return $scope.activeNav; }; this.setActiveNav = function(note){ $scope.activeNav = note; }; } }; });
return this to the controller:
angular.module('NoteWrangler') .directive('nwNav', function() { return { restrict: 'E', controller: function($scope) { $scope.activeNav = 'Notes'; this.getActiveNav= function(){ return $scope.activeNav; }; this.setActiveNav = function(note){ $scope.activeNav = note; }; return this; } }; });
The Parent Is Required
The nwNavItem
directive needs to be able to communicate with the parentnwNav
directive in order to tell when a nav item should be active. Let's go ahead and set that up.
Within the nwNavItem
directive, use the require
option to gain access to the controller from the parent nwNav
directive.
angular.module('NoteWrangler') .directive('nwNavItem', function() { return { restrict: 'E', templateUrl: './templates/directives/nw-nav-item.html', require: '^nwNav' }; });
Give the nwNavItem
directive a link
function. Make sure to fill in all the arguments so that we have access to the controller required from the previous task.
angular.module('NoteWrangler') .directive('nwNavItem', function() { return { restrict: 'E', templateUrl: './templates/directives/nw-nav-item.html', require: '^nwNav', link: function(scope, element, attrs, nwNavCtrl){ } }; });
Using Parent Functionality
We've created the isActive()
and activate()
functions on the scope of the nwNavItem
directive. Within these functions, we'll need to access the controller of the nwNav
directive to set and get which nav item is active.
First, we need a name for the nav item to work. Create a new isolate scope on thenwNavItem
directive and allow it to accept an attribute (@) value called name
.
angular.module('NoteWrangler') .directive('nwNavItem', function() { return { restrict: 'E', templateUrl: './templates/directives/nw-nav-item.html', require: '^nwNav', link: function(scope, element, attrs, nwNavCtrl) { scope.isActive = function() { }; scope.activate = function() { }; }, scope: { name: '@' } }; });
Within the isActive()
function, call the getActiveNav()
function from the required
controller to get the current active nav value. Compare the return value from the controller with the scope.name
value and return the result from the isActive
function.
angular.module('NoteWrangler') .directive('nwNavItem', function() { return { restrict: 'E', templateUrl: './templates/directives/nw-nav-item.html', require: '^nwNav', link: function(scope, element, attrs, nwNavCtrl) { scope.isActive = function() { return nwNavCtrl.getActiveNav()==scope.name; }; scope.activate = function() { }; }, scope: { name: '@' } }; });
We need a way to set the active nav value when a nav item is clicked. In ouractivate()
function, call the setActiveNav()
function on the require
'd controller and pass the scope.name
as an argument.
angular.module('NoteWrangler') .directive('nwNavItem', function() { return { restrict: 'E', templateUrl: './templates/directives/nw-nav-item.html', require: '^nwNav', link: function(scope, element, attrs, nwNavCtrl) { scope.isActive = function() { return nwNavCtrl.getActiveNav()==scope.name; }; scope.activate = function() { nwNavCtrl.setActiveNav(scope.name); }; }, scope: { name: '@' } }; });
The Magic Revealed
Now that we have our nav directives working, we need to hook up the templates.
We can see in the index.html
that we're already passing Notes
and Users
to thename
attribute of our nav item directive. Use data binding to display the value ofscope.name
as the content of our a
tag.
<a class="list-item" href="#/">{{name}}</a>
Give each nwNavItem
a class of active
if it isActive()
.
<a class="list-item" ng-class="{'active': isActive()}" href="#/">{{name}}</a>
On click, call the activate()
method.
<a class="list-item" ng-class="{'active': isActive()}" ng-click="activate()" href="#/">{{name}}</a>
Create an href
for each nav item with a dynamic path using the name
variable. The route should look like: #/value_of_scope_dot_name
and use data binding.
<a class="list-item" ng-class="{'active': isActive()}" ng-click="activate()" href="#/{{name}}">{{name}}</a>
Notice that routes are case sensitive. When we click on Users, it finds no route for/Users
, and therefore redirects to /notes
. Solve this issue by using a lowercase
filter on the name
binding within the route.
<a class="list-item" ng-class="{'active': isActive()}" ng-click="activate()" href="#/{{name | lowercase}}">{{name}}</a>
Since we've added an expression to the href
attribute of our a
tag, we need to change it to ng-href
attribute. Check out the docs to see why this is important.
<a class="list-item" ng-class="{'active': isActive()}" ng-click="activate()" ng-href="#/{{name | lowercase}}">{{name}}</a>
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· SQL Server 2025 AI相关能力初探
· Linux系列:如何用 C#调用 C方法造成内存泄露
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 开源Multi-agent AI智能体框架aevatar.ai,欢迎大家贡献代码
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· AI技术革命,工作效率10个最佳AI工具