(Stuff first...)
together
- Use
ng-click
to add the css styleactive-post
to the clicked element
- do this by creating an
isActive
method in the service that takes an id and returns a boolean
together
- Include the
post.title
in the body of the<post-display>
tag - Remove the
post.title
expression from the directive's template - Add
ng-transclude
to the<strong>
tag - Add
transclude: true
to the directive's return object
together
- Initialize the current module
module('directings');
- Inject in the
$compile
and$rootScope
services
inject(function($compile, $rootScope){...
- Attach
$compile
to a variable we can use outside of theinject
scope - Create a new localized scope from
$rootScope
and attach it to a variable outside theinject
scope
scope = $rootScope.$new();
- Create an element with
angular.element
with the directive in it
var element = angular.element('<div><post-display post="post">{{ post.title }}</post-display></div>');
- Compile the element and attach the new, localized scope to it
compiledDirective = compile(element)(scope);
- Digest the scope
scope.$digest();
- Try the following
it
it("should have put the title in bold", function(){
var el = compiledDirective.find('strong');
expect(el).toBeDefined();
expect(el.text()).toBe(scope.post.title);
});
together
- Create a new directive called "postList"
- Add the new directive to the index after the ListController
<post-list></post-list>
- Give that directive a class of
well
andcol-md-4
- Change the classes of the 2 divs with
col-md-6
tocol-md-4
- Create a new template for post-list.html
- give it the contents of the ListController html in index.html
- Add that template to the
templateUrl
of the directive - Add 'ListController' to the
postList
directive's DDO
controller: 'ListController',
- Add a dependency to the
posts
service to the directive - Add a
controllerAs
to the DDO, give it a value oflc
- or rename it to something more semantically meaningful it is the variable name used in the template
- Test that
on your own
- Change the
controller
on thepostList
directive's DDO to an explicit, inline controller
controller: function(){ ... },
- give that controller the same contents of the List Controller
on your own
beforeEach
and initialize the module- Use
module(function($provide){ ...
to mock the posts service
- all you'll need is a
posts
var array and a get function that doesn't really have to do anything... but you can just set the value of theposts
var to something (valid).
inject
$rootScope
controller
and$injector
$rootScope
to create a new scopevar $scope = $rootScope.$new();
controller
to create the controllerlistController = $controller('ListController', {$scope: $scope});
$injector
to get an instance of the mockedposts
serviceposts = $injector.get('posts');
Note:listController
andposts
will (probably) need to be used outside of theinject
scope.
- Do a test for the controller's
display
function
- it "should set a current post on the service"
together
Same as above, with the following differences
- The
module
initialization needs to initialize "templates" as well
- refer to the testing a directive of last class
- The
beforeEach
will have to create an angular element for the directive
var element = angular.element('<post-list></post-list>');
- Use that element, and the new
scope
you got from$rootScope
in theinject
, tocompile()
the directive
compiledDirective = compile(element)(scope);
$digest
thescope
- Set a controller variable equal to the compiled directive's controller
controller = compiledDirective.controller('postList');
- Now do the same test from above, using the controller you just set to execute the method
bower install angular-route
- Make sure angular-route.min.js gets added after angular.min.js in gulp and karma
- Import
ngRoute
into the module - Add
<div ng-view></div>
somewhere high up in the index.html template file - Create a "controller.html" file in the templates directory, just throw some text into it
- In "app.js" create a config method that injects
$routeProvider
and then calls$routeProvider
with a singlewhen()
like the following:
.config(['$routeProvider', function($routeProvider){
$routeProvider
.when('/', {
templateUrl: 'templates/controller.html'
});
}]);
Make sure your text shows on the index
on your own
- Migrate everything having to do with the controller app into the controller.html
- Migrate everything having to do with the directive half of the app into directive.html
- and repeat the setup for that (.when('/directive', { ... }))
together
- Create an
otherwise
in the$routeProvider
- Use
redirectTo:
to redirect to the controller template
.otherwise({
redirectTo: '/controller'
});
together
- Just add the following code for a basic bootstrap nav
<nav class="navbar navbar-default">
<div class="container-fluid">
<!-- Brand and toggle get grouped for better mobile display -->
<div class="navbar-header">
<a class="navbar-brand" href="#">Directings</a>
</div>
<!-- Collect the nav links, forms, and other content for toggling -->
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li><a ng-href="#/controller">Controller</a></li>
<li><a ng-href="#/directive">Directive</a></li>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</nav>
on your own
- Use
ng-include
to include a template file that will have the<nav>
in it
- Note: an
ng-include
expects an expression as thesrc
so you need to wrap the template string in single quotes <ng-include src="..."></ng-include>
<div ng-include="..."></div>
Note on testing: There's nothing that's unit testable with routes, unless you really want to check to make sure the variables in the routeProvider are set. But that's like testing a variable assignment. Don't go nuts with unit testing, it's for (listed in order of priority) services, directives and controllers. If you're going to test nothing else, test services. If you can do more testing, do directives. If you feel like you really want to, test controllers. But you can stop there. That's all angular is built to test. Anything else should be tested with e2e testing.