Tuesday, August 20, 2013

Bresleveloper's AngularJS Tutorial : Basic Route / Routing

http://bresleveloper.blogspot.co.il/2013/08/breslevelopers-angularjs-tutorial-table.html

u'll here a lot about angular's $route and $routeProvider, and let me warn u: its awesome and does ITS work great, BUT ONLY ITS JOB. so u should either manage ur app flow / navigation with angular's routing ALONE, or some other way while NOT mixing the angular route.

the good part is that if u use routing right u already have full links "built in" (I mean like www.ursite.com/thing1/filter2) support and browsers entries for back and forward, and that really great and sometimes that's what u need.

lets see why - if we take our previous example and try to "just" add routing like that we'll see that stuff just wont get updated, u can try to add to this all kinds like broadcast ect., the point is that here is where u can easly fall:

our view (I call it problemView cuz I don't use myService.X in it):

<div class="singleItem" ng-repeat="catalogItem in MainCatalog" ng-click="MainItemClick(catalogItem)" >
   <a class="box" href="#" >
      <img ng-src="{{ catalogItem.image }}" width="100">
      <div class="textContainer" >
         <h4>{{ catalogItem.level }} - {{ catalogItem.name }}</h4>
      </div>
   </a>
</div>

our code (Ex 4)

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<style>
   .main { width: 400px; }
   .singleItem { width: 25%; display:inline-block; border: 2px dashed green; }
   .textContainer { text-align: center; }
</style>

<script src="angular.js"></script>
<script >
   var myStudyModule = angular.module('myStudyModule', []);

   myStudyModule.config(function ($routeProvider) {
      console.log("config");
      $routeProvider
        
.when('/', { controller: 'myController', templateUrl: 'Views/problemView.html' })
         .when('/somethingElse/:level', { controller: 'myController', templateUrl: 'Views/problemView.html' })
         .otherwise({ redirectTo: '/' });
   });

   myStudyModule.service('myService', function ($http) {
      console.log("myService");
      var self = this;
     
      self.getDataPromise = function (parentKey, level) {
         console.log("myService.getDataPromise");
         var url = 'Handler1.ashx';
         if (parentKey && level)
            url += '?parentKey=' + parentKey + '&level=' + level;
         return $http.get(url);
      };
   });

   var myController = function ($scope, myService) {
      console.log("myController - NEW INSTANCE");
      $scope.MainCatalog = [];
      
      var getMyData = function (parentKey, level) {
         console.log("myController.getMyData");
         myService.getDataPromise(parentKey, level).success(function (data) {
            $scope.MainCatalog = data;
         });
      };


      getMyData();
      $scope.MainItemClick = function (catalogItem) {
         console.log("$scope.MainItemClick");
         getMyData(catalogItem.key, catalogItem.level + 1);
      };
   };

   myStudyModule.controller(myController);


</script>
</head>
<body>
   <div class="main" ng-app="myStudyModule" ng-controller="myController">
      <ng-view></ng-view>
   </div>
</body>
</html>

that's cuz when ur using $routeProvider its will create a new controller with every change. that thing is really forcing u to make ur controllers very abstracts, pure user behavior managers.
the right way to use routing is like that:

view (simpleView):

<div class="singleItem" ng-repeat="catalogItem in myService.catalog" ng-click="MainItemClick(catalogItem)" >
   <a class="box" href="#" >
      <img ng-src="{{ catalogItem.image }}" width="100">
      <div class="textContainer" >
         <h4>{{ catalogItem.level }} - {{ catalogItem.name }}</h4>
      </div>
   </a>
</div>

code (Ex 5)

var myStudyModule = angular.module('myStudyModule', []);

myStudyModule.config(function ($routeProvider) {
   console.log("config");
   $routeProvider
     
.when('/', { controller: 'myController', templateUrl: 'Views/simpleView.html' })
      .when('/somethingElse/:level', { controller: 'myController', templateUrl: 'Views/simpleView.html' })
      .otherwise({ redirectTo: '/' });
});

myStudyModule.service('myService', function ($http) {
   console.log("myService");
   var self = this;
   self.catalog = [];

  
self.getData = function (parentKey, level) {
      console.log("myService.getMyData");
      var url = 'Handler1.ashx';
      if (parentKey && level)
         url += '?parentKey=' + parentKey + '&level=' + level;
      $http.get(url).success(function (data) {
         console.log("$http.get.success");
         self.catalog = data;
      });
   };


   self.getData();
});
var myController = function ($scope, myService) {
   console.log("myController - NEW INSTANCE");
   $scope.myService = myService;
  

   $scope.MainItemClick = function (catalogItem) {
      console.log("$scope.MainItemClick");
      myService.getData(catalogItem.key, catalogItem.level + 1);
   };
};

myStudyModule.controller(myController);
 


but that's a bit futile and can be very dangerous, we want to use the route parameters for the flow, so angular provides us the $routeParams.
with this way we actually use the anchor's href or $location or $window id needed.

DONT use is in the controller, in my example project (goto toc) ex no.6 is how bad it is, and 7-9 are just more examples about how to use all that but only Ex 10 is the really right one and i'll save for u here and give just no.10:

view (routeView - cuz I use href here):

<div class="singleItem" ng-repeat="catalogItem in myService.catalog" >
   <a class="box" href="#/{{ catalogItem.level + 1 }}" >
      <img ng-src="{{ catalogItem.image }}" width="100">
      <div class="textContainer" >
         <h4>{{ catalogItem.level }} - {{ catalogItem.name }}</h4>
      </div>
   </a>
</div>

code (Ex 10)

var myStudyModule = angular.module('myStudyModule', []);

myStudyModule.config(function ($routeProvider) {
   console.log("config");
   $routeProvider
     
.when('/', { controller: 'myController', templateUrl: 'Views/routeView.html' })
      .when('/:level', { controller: 'myController', templateUrl: 'Views/routeView.html' })
      .otherwise({ redirectTo: '/' });
});
 
       
myStudyModule.service('myService', function ($http, $routeParams) {
   console.log("myService");
   var self = this;
   self.catalog = [];

  
self.getData = function () {
      console.log("myService.getMyData");
      var level = $routeParams.level;
      if (!level)
         level = 1;
     
var parentKey = 1; //this should also come from $routeParams with the same logic as level
      var url = 'Handler1.ashx?parentKey=' + parentKey + '&level=' + level;
      $http.get(url).success(function (data) {
         console.log("$http.get.success");
         self.catalog = data;
      });
   };

  
   //u cant put getData here cuz the service gets only 1 instance unlike the ctrl who gets an instance every route

});
 

var myController = function ($scope, myService) {
   console.log("myController - NEW INSTANCE");
   $scope.myService = myService;
   myService.getData();
};

myStudyModule.controller(myController);
 


Next : http://bresleveloper.blogspot.co.il/2013/08/breslevelopers-angularjs-tutorial-basic_20.html
 

No comments:

Post a Comment