Aarmora
Aarmora

Reputation: 1153

Creating partials with a directive

I'm compiling a feed for my company's different blogs. The format is going to be identical for each feed with only different posts being loaded in, so I'd love to go DRY and use a partial.

We originally were writing out the http request about 10 times (that's how many blogs we have) and then I got this brilliant (or maybe not so much...) idea to try and build a directive that would run the http request with a link attribute that would pull back the data that would be specific to that feed.

So, I want to have a dynamic directive that makes dynamic http requests and receives dynamic data sets that I can then feed to one partial. I would have expected/hoped the {{test}} to change based on the value of the link attribute.

I'm definitely new to angular. Am I going about this the wrong way? Thanks in advance!

app.directive('tabs', function(){
  return {
     restrict: "A",
     scope: false,
     link: function(scope, elem, attrs) {
        scope.test = attrs.link;
        scope.$apply;
        //dynamic $http function here               
  }
}

Plunker

Upvotes: 0

Views: 44

Answers (2)

chubbsondubs
chubbsondubs

Reputation: 38789

Depends on what your goal is. Is it to limit the number of requests being made? Or is it to create something reusable so you can create a directive that can be plunked down and handle any blog? These aren't mutually exclusive, but solving one doesn't necessarily solve the other.

Here's roughly what I'd do.

app.directive('blog', ['BlogService', function(BlogService) {
    return {
       restrict: 'A',
       templateUrl: '/app/views/blog.html',
       scope: {
           url: '='
       },
       controller: function($scope) {
          $scope.loadFeed = function() {
              $scope.loading = true;
              BlogService.loadFeed( $scope.url ).success( function(result) {
                  $scope.feed = result.feed;
              } ).complete( function() {
                  $scope.loading = false;
              });
          }
       },
       link: function(scope, element, attribs) {
          scope.$watch('url', function(newVal,oldVal) {
             if( newVal ) {
                scope.loadFeed( scope.url );
             }
          });
       }
}]);

The template:

<div class="feed">
    <span ng-show="loading">Loading feed. Please wait...</span>
    <ul ng-hide="loading">
        <li ng-repeat="post in feed">
           <h1>{{post.title}}</h1>
           <h2>{{post.date}}</h2>
           <p>{{post.description}}</p>
        </li>
    </ul>
</div>

The service:

app.factory( 'BlogService', [ '$http', function($http) {
   return {
      loadFeed: function(url) {
         return $http.get( url );
      },
      loadAllBlogs: function() {
         // this might be a service on your service that 
         // returns all of the blogs for each tab maybe.
         return $http.get('/service/blog/all'); 
      }
   }
}]);

Now you can roll this up into a larger controller that understands your individual feeds and it can set the url on your feeds like:

<div>
   <ul class="tabs">
      <li ng-repeat="blog in blogs" ng-click="selectBlog(blog)>blog.name</li>
   </ul>

   <!-- here is where I use the directive above -->
   <div blog url="selectedBlog.url"></div>
</div>

Plunker

Upvotes: 1

Umidbek
Umidbek

Reputation: 1504

Try this

app.directive('tabs', ['$http', function($http) {
    return {
        restrict: "A",
        scope: false,
        link: function(scope, elem, attrs) {
            $http.get(attrs.link).success(angular.noop);
    }
}]);

Require $http service from directive, and use it in link

Upvotes: 0

Related Questions