deeleman / learning-angular2

Code samples repository for the examples provided in "Learning Angular 2", published by Packt Publishing - THE BOOK COVERS UP TO RC.1 and hence is severely OUTDATED. PLEASE REFER TO THE LATEST EDITIONS INSTEAD.
https://www.packtpub.com/web-development/learning-angular-2
108 stars 59 forks source link

Chapter 4 - various things #20

Closed vulkanino closed 8 years ago

vulkanino commented 8 years ago

At page 103 you correctly write let inside the ngFor expression, but at page 105 in the same code block you go back to the old # which gives a "deprecated" error in the console.

In the same code listing you boldify the "Due" block as if it was a new piece of code, but it didn't change from the previous at page 103.

Besides these typo, what I'm not liking much in Angular 2 so far is that in the views I can access private member variables as if they were public. Doesn't this break the efforts done to make TypeScript so typed and OO?

I have coded the Task differently than you, in my code it is a class and not an interface, with private fields and a toggle method:

class Task
{
    constructor(name:string, deadline: Date, pomodoros: number)
    {
        this.name=name;
        this.deadline = deadline;
        this.queued = false;
        this.pomodoros = pomodoros;
    }

    toggle() : void
    {
        this.queued = ! this.queued;
    }

    private name: string;
    private deadline: Date;
    private queued: boolean;
    private pomodoros: number;
}

I removed the TaskService altogether and did:

@Component(
{
    selector: 'pomodoro-tasks',
    styleUrls: ['pomodoro-tasks.css'],
    templateUrl: 't-pomodoro-tasks.html'
})
class TaskComponent
{
    private today: Date;
    private tasks: Array<Task> = [];

    constructor()
    {
        this.tasks.push(new Task("Code an HTML table", new Date("Jun 23 2015"), 1));
        this.tasks.push(new Task("Sketch a wireframe for the new homepage", new Date("Jun 24 2016"), 2));
        this.tasks.push(new Task("Style table with bootstrap styles", new Date("Jun 25 2017"), 1));
        this.tasks.push(new Task("Reinforce SEO with custom sitemap", new Date("Jun 26 2017"), 3));

        this.today = new Date();
    }

    toggleTask(task: Task): void
    {
        task.toggle();
    }
}

In an effort to make the code more object oriented, but then in the view I copied your code:

 <tr *ngFor="let task of tasks; let i=index">
                    <th scope="row">{{i+1}}
                        <span *ngIf="task.queued" class="label label-info">In coda</span>
                    </th>

and was surprised to see that task.queued is perfectly in scope and accessible even though it is private in the containing class. What is your opinion about this encapsulation break?

Thanks.

deeleman commented 8 years ago

Thanks for reporting these typos. In regards of your comments, just a few notes:

Besides these typo, what I'm not liking much in Angular 2 so far is that in the views I can access private member variables as if they were public. Doesn't this break the efforts done to make TypeScript so typed and OO?

This issue is not related to Angular 2 indeed, but to TypeScript itself, and is part of the language design. Simply put, the privacy of members are only enforced within the compiler. If you set a private member and try to access from another instance object, the compiler will complain. Things turn to be different once TypeScript has been traspiled to JavaScript and you access class members from within a template.

Back tot he TypeScript discussion, you can find an interesting thread about the matter and several workarounds for this issue here.

I removed the TaskService altogether

I guess you did this to simplify the exercise but I'd like to remark that this is a bad design and you should avoid creating any sort of tight coupling between data management layers and components definition at all times.

Thanks again for your comments. Hope you're enjoying the book and find it helpful.