3

I have been developing an AngularJS Directive which is supposed to work as a stand alone widget which can be configured by setting attributes in the form of Objects. My Primary Objectives are below:

  1. Do the processing inside directive based on the Object passed in attributes. the Processing does involve fetching REST API response. SO I am using controllers to achieve that.
  2. After My Directive does some processing, It may change the Object which my Parent Controller should be able to change.

Below is the sample code which covers up my objective.

Directive Usage:

<post-listing page-id="currentPage.id" config="postConfig" posts="posts" />

Code for Directive

'use strict';

angular.module('myApp')
    .directive('postListing', function () {
      return {
          templateUrl: '/views/directive.post-listing.html',
          restrict: 'EA',
          scope: {
              page_id:"=", 
              config:"=",
              posts:"=",
          },
          controller: "DirectivePostListingCtrl"

        };
    });

Code for Directive Controller:

'use strict';

angular.module('myApp')
    .controller('DirectivePostListingCtrl', function ($scope, $rootScope, $routeParams)
    {
        // Here I want to access the page_id and config as the actual value

        // Here I will also update the posts array which is exposed to outside of directive.
    });

Code for template:

<h4>Displaying Posts for {{page.title}}</h4>
<ul>
    <li ng-repeat="p in posts" >{{p.title}}</li>
</ul>

When I run this code, it says $scope.page_id either "undefined" or it says "currentPage.id" (based on the operator selected = or @ ) where I expect it to be the value of currentPage.id .

Please suggest.

Thanks in advance.

Balwant Singh
  • 287
  • 5
  • 14
  • You should try `$watch` once for `$scope.page_id`, I am sure these are populated using some service. So its not available when controller is initialized. alternatively you can use `$broadcast`. – Satpal Dec 25 '14 at 10:53
  • can you list the codes in controller how you access page_id and config? – hjl Dec 25 '14 at 11:05

3 Answers3

4

You are not following camelCase naming rule for isolated scope property names. You will be able to access page id if you use this config:

scope: {
    pageId: "=", 
    config: "=",
    posts: "=",
},

and in controller:

console.log($scope.pageId);
dfsq
  • 191,768
  • 25
  • 236
  • 258
0
<post-listing data="PostListing" />

// use this is in controller

'use strict';

angular.module('myApp')
    .controller('DirectivePostListingCtrl', function ($scope, $rootScope, $routeParams)
    {
        $scope.PostListing={}
        $scope.PostListing.pageId=//Your Data
        $scope.PostListing.config=//Your Data
        $scope.PostListing.posts=//Your Data
    }); 

Make Changes in your directive

angular.module('myApp')
    .directive('postListing', function () {
      return {
          templateUrl: '/views/directive.post-listing.html',
          restrict: 'EA',
          scope: {
              data:"="
          },
          controller: "DirectivePostListingCtrl"

        };
    });

Use code in Template like

<ul>
    <li ng-repeat="p in data.posts" >{{p.title}}</li>
</ul>
Rashid
  • 37
  • 1
  • 10
0

there are three main problems:

  1. with @, the attribute needs to be an evaluated value. So in the attribute it should be like: page-id="{{currentPage.id}}". See a better explanation here: https://stackoverflow.com/a/14063373.

  2. As @dfsq said, page_id should be pageId.

Here is the plunker with the solution: http://plnkr.co/edit/z843xZjIDQVe11edYLDR?p=preview

  1. Your custom directive shouldn't be a void element. It is better to close the tag like </post-listing> to avoid weird behaviours. In my case, chrome is wrapping everything inside the directive till the end of the div. Here is a plunker using transclude to show that my paragraph is being wrapped inside the custom directive: http://plnkr.co/edit/H3mDdi631flnC8AG2Q8i?p=preview
Community
  • 1
  • 1