1

I am paginating posts in my component and I am sending the number of posts from the post component to pagination component to like this:

<pagination [items]="posts.length" (page-changed)="onPageChanged($event)"></pagination>

I have set up the pagination component and the parameter items like so:

export class PaginationComponent implements OnChanges {
  @Input() items: number;

But, I get an error:

EXCEPTION: Template parse errors:
Can't bind to 'items' since it isn't a known native property ("
        </select>
        <spinner [visible]="postsLoading"></spinner>
        <pagination [ERROR ->][items]="posts.length" (page-changed)="onPageChanged($event)"></pagination>
        <ul class="list-g"): PostsComponent@10:20

What am I doing wrong?

This is the complete pagination component:

import {Component, Input, Output, EventEmitter} from 'angular2/core';
import {OnChanges} from 'angular2/core';

@Component({
      selector: 'pagination',
    template: `
    <nav *ngIf="items > pageSize">
        <ul class="pagination">
            <li [class.disabled]="currentPage == 1">
                <a (click)="previous()" aria-label="Previous">
                <span aria-hidden="true">&laquo;</span>
                </a>
            </li>
            <li [class.active]="currentPage == page" *ngFor="#page of pages" (click)="changePage(page)">
                <a>{{ page }}</a>
            </li>
            <li [class.disabled]="currentPage == pages.length">
                <a (click)="next()" aria-label="Next">
                <span aria-hidden="true">&raquo;</span>
                </a>
            </li>
        </ul>
    </nav>
`
})
export class PaginationComponent implements OnChanges {
  @Input() items: number;
    @Input('page-size') pageSize = 10;
    @Output('page-changed') pageChanged = new EventEmitter();
    pages: any[];
    currentPage;

    ngOnChanges(){
    this.currentPage = 1;

        var pagesCount = Math.ceil(this.items / this.pageSize);
        this.pages = [];
        for (var i = 1; i <= pagesCount; i++)
            this.pages.push(i);
    }

    changePage(page){
        this.currentPage = page;
        this.pageChanged.emit(page);
    }

    previous(){
        if (this.currentPage == 1)
            return;

        this.currentPage--;
        this.pageChanged.emit(this.currentPage);
    }

    next(){
        if (this.currentPage == this.pages.length)
            return;

        this.currentPage++;
        this.pageChanged.emit(this.currentPage);
    }
}

And this is the posts component:

import {Component, OnInit} from 'angular2/core';
import {PostService} from '../services/post.service';
import {UserService} from '../services/user.service';
import {SpinnerComponent} from './spinner.component';
import {PaginationComponent} from './pagination.component';

@Component({
    templateUrl: 'app/templates/posts.template.html',
    styles: [`
        .posts li { cursor: default; }
        .posts li:hover { background: #ecf0f1; }
        .list-group-item.active,
        .list-group-item.active:hover,
        .list-group-item.active:focus {
            background-color: #ecf0f1;
            border-color: #ecf0f1;
            color: #2c3e50;
        }
        .clickable {
            cursor: pointer;
        }
        .thumbnail {
            border-radius: 100%;
        }
    `],
    providers: [PostService, UserService],
    directives: [SpinnerComponent]
})
export class PostsComponent implements OnInit {
      posts = [];
    users = [];
    pagedPosts = [];
    postsLoading;
    commentsLoading;
    currentPost;
    pageSize = 10;

    constructor(
        private _postService: PostService,
        private _userService: UserService) {
    }

    ngOnInit() {
        this.loadUsers();
        this.loadPosts();
    }

    private loadUsers(){
        this._userService.getUsers()
          .subscribe(users => this.users = users);
    }

    private loadPosts(filter?){
        this.postsLoading = true;
            this._postService.getPosts(filter)
                .subscribe(
              posts => {
                  this.posts = posts;
                  this.pagedPosts = this.getPostsInPage(1);
              },
              null,
              () => { this.postsLoading = false; });
    }

    reloadPosts(filter){
        this.currentPost = null;

        this.loadPosts(filter);
    }

    select(post){
            this.currentPost = post;

        this.commentsLoading = true;
        this._postService.getComments(post.id)
            .subscribe(
                comments => this.currentPost.comments = comments,
                null,
                () => this.commentsLoading = false);
    }

    onPageChanged(page) {
          this.pagedPosts = this.getPostsInPage(page);
    }

    private getPostsInPage(page){
        var result = [];
            var startingIndex = (page - 1) * this.pageSize;
        var endIndex = Math.min(startingIndex + this.pageSize, this.posts.length);

        for (var i = startingIndex; i < endIndex; i++)
            result.push(this.posts[i]);

        return result;
    }
}

And this is the template:

<h1>Posts</h1>
<div class="row">
    <div class="col-md-6">
       <select class="form-control" (change)="reloadPosts({ userId: u.value })" #u>
            <option value="">Select a user...</option>
            <option *ngFor="#user of users" value="{{ user.id }}">
                {{ user.name }}
            </option>
        </select>
        <spinner [visible]="postsLoading"></spinner>
        <pagination [items]="posts.length" (page-changed)="onPageChanged($event)"></pagination>
        <ul class="list-group posts">
            <li *ngFor="#post of pagedPosts" class="list-group-item" [class.active]="currentPost == post" (click)="select(post)">
                {{ post.title }}
            </li>
        </ul>
    </div>
    <div class="col-md-6">
        <div *ngIf="currentPost" class="panel panel-default">
            <div class="panel-heading">
                <h3 class="panel-title">{{ currentPost.title }}</h3>
            </div>
            <div class="panel-body">
                <p>{{ currentPost.body }}</p>
                <hr/>
                <spinner [visible]="commentsLoading"></spinner>
                <div class="media" *ngFor="#comment of currentPost.comments">
                    <div class="media-left">
                        <a href="#">
                            <img class="media-object thumbnail" src="http://lorempixel.com/80/80/people?random={{ comment.id }}" alt="...">
                        </a>
                    </div>
                    <div class="media-body">
                        <h4 class="media-heading">
                            {{ comment.name }}
                        </h4>
                        {{ comment.body }}
                    </div>
                </div>
            </div>
        </div>
    </div>
</div>
5
  • you code looks fine ,just check if you saved your files or restart your project. Commented Mar 8, 2017 at 19:05
  • I did, but I still get the same error Commented Mar 8, 2017 at 19:09
  • Can you post some more code? I tried it out, and it works in my case... Maybe just remove the built code and re-run the build-process? This often helps... Commented Mar 8, 2017 at 19:16
  • Ah, have you set the "selector" to pagination in the PaginationComponent? Commented Mar 8, 2017 at 19:16
  • I have updated question with more code. I am using the selector 'pagination'. Commented Mar 8, 2017 at 19:20

1 Answer 1

1

I forgot to add a pagination component to the directives array in the posts component.

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

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.