Se ha denunciado esta presentación.
Utilizamos tu perfil de LinkedIn y tus datos de actividad para personalizar los anuncios y mostrarte publicidad más relevante. Puedes cambiar tus preferencias de publicidad en cualquier momento.

Angular JS blog tutorial

3.761 visualizaciones

Publicado el

Tutorial to create a blog using AngularJS.
The slides were originally used for a study
meetup at our office.

Publicado en: Tecnología
  • Sé el primero en comentar

Angular JS blog tutorial

  1. 1. ANGULARJS INTRODUCTIONby @DanielPerez ClaudeTech
  2. 2. LEAVES STATIC WEBSITE BUILD TOOL Dependsonly onNodeJS. Uses: Yeoman Grunt Bower Jade(or EJS) Stylus(or lessor plainCSS) Coffee(or plainJS) Installwith: $npminstall-gleaves $leavessetup Checkout for moreinfo.thedocs
  3. 3. PROJECT CREATION $leavesnewangular-blog $cdangular-blog $leavesinstalljqueryangularangular-resourcebootstrapangular-ui-routermarkdown Renameassets/js/app.coffeetoassets/js/app.js, eraseassets/css/main.stylcontent andedit views/layout.jade. //views/layout.jade html head .... link(rel="stylesheet"href="components/bootstrap/dist/css/bootstrap.min.css") link(rel="stylesheet"href="components/bootstrap/dist/css/bootstrap-theme.min.css") script(src="components/jquery/dist/jquery.min.js") script(src="components/angular/angular.min.js") script(src="components/angular-resource/angular-resource.min.js") script(src="components/angular-ui-router/release/angular-ui-router.min.js") script(src="components/bootstrap/dist/js/bootstrap.min.js") script(src="js/app.js") body blockcontent
  4. 4. START HACKING Whenyouaredonewithbasic setup,run $leaves andstart hacking. FOR SCEPTICAL PEOPLE If youdonot want touseleaves,check about basic Angular setup.my blog post
  5. 5. TRY ANGULARJS Initializeapplication //views/layout.jade html head ... body(ng-app="") blockcontent Try two-way databinding: Output variablevaluewith: {{variable}}. Changevariablevaluewith: ng-model="variable" //views/index.jade extends./layout.jade blockcontent input(ng-model="variable") span{{variable}}
  6. 6. TRY ANGULARJS Initializevariable: //views/index.jade extends./layout.jade blockcontent div(ng-init="variable='plaintext'") span{{variable}} Youcanuseany element,not just divandspan.
  7. 7. TRY ANGULARJS Usecontroller toinitializevariable. //views/index.jade div(ng-controller="TestCtrl") span{{variable}} Definecontroller inJS file. $scopeisinjectedby Angular oninstanciation. //assets/js/app.js functionTestCtrl($scope){ $scope.variable="myvariabletext"; } Angular uses toinstanciatecontrollers,services,etc.DI
  8. 8. TRY ANGULARJS React toevents: //views/index.jade div(ng-controller="TestCtrl") span{{variable}} button(ng-click="action()") //assets/js/app.js functionTestCtrl($scope){ $scope.variable="myvariabletext"; $scope.action=function(){ $scope.variable="Ijustclicked!"; }; }
  9. 9. CREATE BLOG Createblog withfollowing functionalities: List posts List postsby category Showpost Createnewpost WewillusepreparedAPI toworkwith. Authentication/authorizationwillbefor next time. Sampleisavailableat .angular-blog-sample.herokuapp.com Fullsourcecodeisavailableat . github.com/claudetech-meetups/angular-blog- sample
  10. 10. AVAILABLE API TheavailableAPI callsare GET /posts GET /posts/:id POST /posts GET /categories POST /categories API isavailableat: http://angular-tutorial-api.herokuapp.com/
  11. 11. CREATE BASIC LAYOUT Addheader toviews/layout.jade html head .... body(ng-app="") .container nav.navbar.navbar-default .container-fluid .navbar-header a.navbar-brand(href="#")Blog .row .col-xs-8 blockcontent .col-xs-4 .block.categories h3Categories ul.list-unstyled li:a.small(href="#")Plentyofcategories .block.admin h3Admin ul.list-unstyled li:a.small(href="#")Addpost
  12. 12. CREATE BASIC LAYOUT Createempty views/posts/index.jadeandedit views/index.jade. //views/index.jade extends./layout.jade blockcontent include./posts/index
  13. 13. BUILD POST LIST Createcontroller inJS file: functionPostIndexCtrl($scope){ $scope.post={ id:1, title:"Posttitle", content:"Postcontent", createdAt:newDate() }; } Wrappost list inacontroller andusedummy data .posts(ng-controller="PostIndexCtrl") .post.row .row .col-xs-12 h2{{post.title}} small.date{{post.createdAt}} .row.content .col-xs-12{{post.content}} .row .col-xs-12 a.small(href="#")Seemore andcreatethecontroller.
  14. 14. SOME ISSUES {{variable}}appearsonpageload Dateformat isstrange Nolinebreakincontent Content may bevery long
  15. 15. SOME SOLUTIONS Useng-bindinsteadof {{}} Usedatefilter Wewillseehowtorender markdownincontent later on UselimitTofilter .posts(ng-controller="PostIndexCtrl") .post.row .row .col-xs-12 h2(ng-bind="post.title") small.date(ng-bind="post.createAt|date:'y/M/d'") .row.content .col-xs-12(ng-bind="post.content|limitTo:100") .row .col-xs-12 a.small(href="#")Seemore
  16. 16. MAKE IT A LIST Adddummy datainthecontroller. functionPostIndexCtrl($scope){ $scope.posts=[{ id:1, title:"Posttitle", content:"Postcontent", createdAt:newDate() },{ id:2, title:"Posttitle2", content:"Postcontent2", createdAt:newDate() }]; } Useng-repeat .posts(ng-controller="PostIndexCtrl") .post.row(ng-repeat="postinposts") ...
  17. 17. SHOW SINGLE POST Createviews/posts_show.jade,wewillextendlayout.jadefor now. extends./layout.jade blockcontent .post.row(ng-controller="PostShowCtrl") .row .col-xs-12 h2{{post.title}} small.date{{post.createdAt|date:'y/M/d'}} .row.content .col-xs-12{{post.content}} createPostShowCtrlfunction. //assets/js/app.js .... functionPostShowCtrl($scope){ $scope.post={ id:1, title:"Posttitle", content:"Postcontent", createdAt:newDate() }; } Youcantry toaccessyour page: localhost:9000/posts_show.html
  18. 18. SOME ISSUES Better modularizecontrollers Wedon't want another page Wewant content inmarkdown
  19. 19. MODULARIZATION Let'sstart by splitting files. //assets/js/controllers/posts/index.js functionPostIndexCtrl($scope){ ..... } //assets/js/controllers/posts/show.js functionPostShowCtrl($scope){ ..... } //views/layout.jade html head .... script(src="js/app.js") script(src="js/controllers/posts/index.js") script(src="js/controllers/posts/show.js") body(ng-app="") ...
  20. 20. ANGULAR MODULES Angular hasnativemodules.DeclareBlogAppmodulewithnodepencies. //assets/js/app.js angular.module('BlogApp',[]); Declarecontrollersaspart of themodule. //assets/js/controllers/posts/index.js angular.module('BlogApp').controller('PostIndexCtrl',[ '$scope',function($scope){ ... } ]); Samegoesfor PostShowCtrl.
  21. 21. ROUTING Routeinorder tobeabletohave /#/->allposts /#/posts/:id->post withid=:id /#/posts/new->newpost First,add depency tothemodule.ui.router //assets/js/app.js angular.module('BlogApp',[ 'ui.router' ]);
  22. 22. SETUP VIEW First,addtheviewwheretodisplay thecontent of theroute. //views/index.jade extends./layout.jade blockcontent div(ui-view)
  23. 23. SETUP ROUTER Configuretoredirect to/whennoroutefound,andconfiguretheroutes. //assets/js/app.js ... angular.module('BlogApp').config([ '$stateProvider','$urlRouterProvider',function($stateProvider,$urlRouterProvider){ $urlRouterProvider.otherwise('/'); $stateProvider .state('index',{ url:'/', templateUrl:'posts/index.html' }) .state('show',{ url:'/posts/:id', templateUrl:'posts/show.html' }); } ]); Then,removetheextendsandblockcontentfrom views/posts_show.jade: wedon't needthewholelayout.For consistency, moveviews/post_show.jadetoviews/posts/show.jade. Youcannowaccessyour route: localhost:9000/#/posts/1
  24. 24. SETUP ROUTER Controllersshouldbedefinedinroutes. //assets/js/app.js .state('index',{ url:'/', templateUrl:'posts/index.html', controller:'PostIndexCtrl' }) .state('show',{ url:'/posts/:id', templateUrl:'posts/show.html', controller:'PostShowCtrl' }); andremovedfromviews/posts/index.jadeand views/posts/show.jade. //views/posts/show.jade .post.row//nong-controlleranymore ...
  25. 25. ADD LINKS usesui-sreftomakelinkinsteadof normalhrefor ng-href attributes. ui-router //views/posts/index.jade ... a.small(ui-sref="show({id:post.id})")Seemore
  26. 26. USE API AddngResourcemoduleasadependency. //assets/js/app.js angular.module('BlogApp',[ 'ui.router', 'ngResource' ]); ... Try it //assets/js/controllers/posts/index.js angular.module('BlogApp').controller('PostIndexCtrl',[ '$scope','$resource',function($scope,$resource){ //noneedfordummydataanymore varPost=$resource('http://angular-tutorial-api.herokuapp.com/posts/:id'); Post.query(function(posts){ console.log(posts[0]); $scope.posts=posts; }); } ]);
  27. 27. RESOURCE FACTORY Wewant tobeabletousePostresourceanywhere. Let'smakeit afactory. //assets/js/resources/post.js angular.module('BlogApp').factory('Post',[ '$resource',function($resource){ return$resource('http://angular-tutorial-api.herokuapp.com/posts/:id'); } ]); andincludeit inviews/layout.jade html head ... script(src="js/resources/post.js")
  28. 28. USE RESOURCE FACTORY //assets/js/controllers/index.js angular.module('BlogApp').controller('PostIndexCtrl',[ '$scope','Post',function($scope,Post){ Post.query(function(posts){ $scope.posts=posts; }); } ]);
  29. 29. FETCH SINGLE POST Use$stateParamstoget id,andget post fromserver. //assets/js/controllers/posts/show.js angular.module('BlogApp').controller('PostShowCtrl',[ '$scope','$stateParams','Post',function($scope,$stateParams,Post){ Post.get({id:$stateParams.id},function(post){ $scope.post=post; }); } ]);
  30. 30. CREATE CATEGORY FACTORY //assets/js/resources/category.js angular.module('BlogApp').factory('Category',[ '$resource',function($resource){ return$resource('http://angular-tutorial-api.herokuapp.com/categories/:id'); } ]); andaddit tolayout.jade
  31. 31. NEW POST CONTROLLER CreatenewJS file,andafreshpost tobind. //assets/js/controllers/posts/new.js angular.module('BlogApp').controller('PostNewCtrl',[ '$scope','Post',function($scope,Post){ $scope.post=newPost(); } ]); andincludeit inviews/layout.jade script(src="js/controllers/posts/new.js")
  32. 32. CREATE NEW POST TEMPLATE Bindthemodelcreatedinthecontroller. //views/posts/new.jade h2Createnewpost form .form-group label(for="title")Title input#title.form-control(type="text"placeholder="Title"ng-model="post.title") .form-group label(for="content")Content textarea#content.form-control(rows="10"ng-model="post.content") .form-group select.form-control(ng-model="post.category_id") input.btn.btn-default(type="submit"value="Create")
  33. 33. ADD A NEW ROUTE Careful,order matters! $stateProvider .state('index',{ ..... }) .state('new',{ url:'/posts/new', templateUrl:'posts/new.html', controller:'PostNewCtrl' }) .state('show',{ ..... }); Andset link //views/layout.jade ... .block.admin h3Admin ul.list-unstyled li:a.small(ui-sref="new")Addpost
  34. 34. RESOLVE CATEGORIES Better havecategoriesbeforeloading template.Usecustommadepromiseand resolveAPI result. //assets/js/app.js ... .state('new',{ url:'/posts/new', templateUrl:'posts/new.html', controller:'PostNewCtrl', resolve:{ categories:['$q','Category',function($q,Category){ vardeferred=$q.defer(); Category.query(function(categories){ deferred.resolve(categories); }); returndeferred.promise; }] } }) .state('show',{ ....
  35. 35. RESOLVE CATEGORIES Usethecategoriesresolvedinthecontroller. //assets/js/controllers/posts/new.js angular.module('BlogApp').controller('PostNewCtrl',[ '$scope','Post','categories',function($scope,Post,categories){ $scope.post=newPost(); $scope.categories=categories; } ]);
  36. 36. USE NG-OPTIONS Dynamically showcategoriesinselectusing ng-options. form ... select.form-control( ng-model="post.category_id" ng-options="c.idasc.nameforcincategories" )
  37. 37. CREATE POST React tosubmit event //views/posts/new.jade form(ng-submit="createPost()") Addhandler for submit event. //js/controllers/posts/new.js angular.module('BlogApp').controller('PostNewCtrl',[ '$scope','Post','$state','categories',function($scope,Post,$state,categories){ ... $scope.createPost=function(){ $scope.post.$save(function(post){ $state.go('index',{id:post.id}); }); }; ...
  38. 38. FORMAT MARKDOWN Wearegoing tocreateafilter toformat markdown. //assets/js/filters/markdown.js angular.module('BlogApp').filter('markdown',[ '$sce',function($sce){ returnfunction(input){ if(!input){ return''; } return$sce.trustAsHtml(markdown.toHTML(input)); }; } ]); inputisthevaluetoconvert tomarkdown.Wereturnempty string if undefined. ThemarkdownisformattedinHTML,weneedtotrust theinput totellAngular it issafe.
  39. 39. DISPLAY FORMATTED MARKDOWN Weuseng-bind-htmltodisplay HTML andnot escapedvalues. //views/posts/show.jade .post.row .... .row.content .col-xs-12(ng-bind-html="post.content|markdown")
  40. 40. CREATE CATEGORIES CONTROLLER Asfor posts,query toget allthecategories. //assets/js/controllers/categories/index.js angular.module('BlogApp').controller('CategoryIndexCtrl',[ '$scope','Category',function($scope,Category){ Category.query(function(categories){ $scope.categories=categories; }); } ]);
  41. 41. SHOW CATEGORIES Createpartial //views/categories/index.jade .block.categories(ng-controller="CategoryIndexCtrl") h3Categories ul.list-unstyled li(ng-repeat="categoryincategories") a.small(ui-sref="index({category:category.id})"ng-bind="category.name") Changelayout tousepartial. //views/layout.jade .... .col-xs-4 include./categories/index .block.admin h3Admin ul.list-unstyled li:a.small(ui-sref="new")Addpost
  42. 42. UPDATE ROUTES Updateindex routestotakecategoryquery parameter. //assets/js/app.js ... $stateProvider .state('index',{ url:'/?category', templateUrl:'posts/index.html', controller:'PostIndexCtrl' }) Thisisneededtopasscategorytoui-srefandtoreadit from $stateParams.
  43. 43. FILTER QUERY Checkif thereisacategory definedandadapt query. //assets/js/controllers/posts/index.js angular.module('BlogApp').controller('PostIndexCtrl',[ '$scope','$stateParams','Post',function($scope,$stateParams,Post){ varsearch=$stateParams.category?{category_id:$stateParams.category}:{}; Post.query(search,function(posts){ $scope.posts=posts; }); } ]);

×