0

I am attempting to build what should be a very simple custom directive using some hierarchical data. Each page in the list has subpages and the data is of the form:

{"Title 1": "Page Title", "Id": "1", "Pages": {"Title 1.1": "Page Title 1.1", "Id": "2"}, {"Title 1.2": "Page Title 1.2", "Id": "3"}}

and so on. The data here is just a quick illustration - there is no issue with either the data or retrieval method.

I have a directive controller set up as:

app.directive('pageSelectList', function () {
return {
    restrict: 'EA',
    replace: true,
    scope: {
        pageList: '='
    },
    templateUrl: '/Scripts/App/Directives/Templates/PageSelectList.html',
    link: function (scope, elem, attrs) { }
   };
});

The template is:

<ul class="page-list page-root">
    <li ng-repeat="p in pageList.Pages">{{ p.Title }}</li>
</ul>

The directive is used with data drawn from the parent scope ($scope.listOfPages).

However, when using it, nothing is displayed - it's blank. Strangely, when replacing the directive template with the following markup:

<p>{{ pageList.Title }}</p>

The expected markup <p>Title 1</p> is shown.

It would appear that the directive has some sort of issue with either ng-repeat or that the data being used in the repeat is a subobject of the pageList object passed.

Furthermore, when the markup for the directive is just used in a regular page with data from the parent scope, there is no problem at all. It seems to be a problem with the directive itself.

EDIT

This is the page controller that is populating the data for the directive:

var pageEditController = function ($scope, $rootScope, $state, $stateParams, pageService) {
$scope.page = {};
$scope.errorMessage = "";

getPage(); // This is for other data on the page and not directly linked to directive issue.

getPages(); // This is to get the directive data

function getPage() { // Just an http get method for $scope.page }}

function getPages() {
    pageService.getTree()
        .success(function (result) {
            $scope.pageList = result.Result; // This is where the directive data is loaded into scope
        })
        .error(function (error) {
            $scope.errorMessage = 'Unable to load pages';
        });
     };

});

Further strange behaviour:

A template with this:

<p>{{ pageList.Title }}</p>

shows the Title OK.

This:

<p>{{ pageList.Title }}</p><p>{{ pageList.Id }}</p>

shows nothing at all. Obviously ng-repeat in original example doesn't work either.

11
  • 2
    could you provide the code you're actually using? Commented Nov 4, 2015 at 11:19
  • 1
    How are you calling the 'pageSelectList' directive? Commented Nov 4, 2015 at 11:40
  • do you see any errors in console? except not valid JSON in OP - your code seems work Commented Nov 4, 2015 at 12:25
  • can you provide plunkr? and sample value for pageList? Commented Nov 4, 2015 at 12:43
  • 1
    just see error in console: Error: [$compile:tplrt] Template for directive 'pageSelectList' must have exactly one root element. PageSelectList.html, here fixed plunkr all work fine Commented Nov 4, 2015 at 14:35

2 Answers 2

1

In the directive, you have mentioned as "pageList". But in the template, you are accessing it using "PageList". So, I guess that it may solve using issue.

Sign up to request clarification or add additional context in comments.

Comments

0

As we detect in comment: your code work OK, and problem with template for directive.

When you use replace:true in your directive, template that you load must have exactly one root element otherwise you get next error:

Error: [$compile:tplrt] Template for directive 'pageSelectList' must have exactly one root element. PageSelectList.html
https://docs.angularjs.org/error/$compile/tplrt?p0=pageSelectList&p1=PageSelectList.html

So, for solving you have two way:

1) wrap your template in container, like a div

<div>
    your directive 
    <p>{{ pageList.Title }}</p><p>{{ pageList.Id }}</p>
</div>

2) remove flag replace, or use it replace: false.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.