(Stuff first...)
together
- Use
ng-clickto add the css styleactive-postto the clicked element
- do this by creating an
isActivemethod in the service that takes an id and returns a boolean
together
- Include the
post.titlein the body of the<post-display>tag - Remove the
post.titleexpression from the directive's template - Add
ng-transcludeto the<strong>tag - Add
transclude: trueto the directive's return object
together
- Initialize the current module
module('directings');
- Inject in the
$compileand$rootScopeservices
inject(function($compile, $rootScope){...
- Attach
$compileto a variable we can use outside of theinjectscope - Create a new localized scope from
$rootScopeand attach it to a variable outside theinjectscope
scope = $rootScope.$new();
- Create an element with
angular.elementwith 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
wellandcol-md-4 - Change the classes of the 2 divs with
col-md-6tocol-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
templateUrlof the directive - Add 'ListController' to the
postListdirective's DDO
controller: 'ListController',
- Add a dependency to the
postsservice to the directive - Add a
controllerAsto 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
controlleron thepostListdirective's DDO to an explicit, inline controller
controller: function(){ ... },- give that controller the same contents of the List Controller
on your own
beforeEachand initialize the module- Use
module(function($provide){ ...to mock the posts service
- all you'll need is a
postsvar array and a get function that doesn't really have to do anything... but you can just set the value of thepostsvar to something (valid).
inject$rootScopecontrollerand$injector
$rootScopeto create a new scopevar $scope = $rootScope.$new();
controllerto create the controllerlistController = $controller('ListController', {$scope: $scope});
$injectorto get an instance of the mockedpostsserviceposts = $injector.get('posts');Note:listControllerandpostswill (probably) need to be used outside of theinjectscope.
- Do a test for the controller's
displayfunction
- it "should set a current post on the service"
together
Same as above, with the following differences
- The
moduleinitialization needs to initialize "templates" as well
- refer to the testing a directive of last class
- The
beforeEachwill have to create an angular element for the directive
var element = angular.element('<post-list></post-list>');
- Use that element, and the new
scopeyou got from$rootScopein theinject, tocompile()the directive
compiledDirective = compile(element)(scope);
$digestthescope- 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
ngRouteinto 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
$routeProviderand then calls$routeProviderwith 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
otherwisein 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-includeto include a template file that will have the<nav>in it
- Note: an
ng-includeexpects an expression as thesrcso 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.