Angular 2 ng For first occurence undefined

时间:2016-09-22 12:13:01

标签: angular

我正在尝试Angular 2而我正面临一个我不明白的奇怪问题。

我制作了一个简单的待办事项清单,当我执行我的应用程序时,我收到以下错误消息:

Error message from Chrome console

我不明白为什么迭代的第一次出现是未定义的。我的阵列是硬编码的,所以我不知道为什么会出现这个问题。 以下是此应用程序的代码:

app.module.ts

import { NgModule }      from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { TodoNavComponent }   from './app.todo-nav';
import { TodoListComponent }   from './app.todo-list';
import { TodoComponent }   from './app.todo';

@NgModule({
  imports:      [ BrowserModule ],
  declarations: [ TodoNavComponent, TodoListComponent, TodoComponent ],
  bootstrap:    [ TodoNavComponent, TodoListComponent, TodoComponent ]
})
export class AppModule { }

app.todo-list.ts

import { Component } from "@angular/core";
import { TodoService } from "./app.service";

@Component({
    selector: "todo-list",
    template: `
        <div class="container">
            <ul class="list-group">
                <todo *ngFor="let todo of todos" [todo]="todo"></todo>
            </ul>
        </div>`,
    providers: [TodoService]
})
export class TodoListComponent {
    todos: any[] = [
        { name: "Do shopping", done: false },
        { name: "Get some gaz for my car", done: true },
        { name: "Download last season of Game of Thrones", done: false }
    ];

    constructor(private service: TodoService) {
        service.todoAdded$.subscribe(
            todo => {
                this.todos.push(todo);
            }
        );
        service.todoRemoved$.subscribe(
            todo => {
                this.todos = this.todos.filter(
                    (value, index, array) => {
                        return todo.name !== value.name;
                    }
                );
            }
        );
    }
}

app.todo.ts

import { Component, OnDestroy, Input  } from "@angular/core";
import { TodoService } from "./app.service";
import { Subscription }   from 'rxjs/Subscription';

@Component( {
    selector: "todo",
    template: `
        <li class="list-group-item">
            <i class="pull-right glyphicon glyphicon-remove" (click)="remove()"></i>
            {{todo.name}}
        </li>`,
    providers: [TodoService]
})
export class TodoComponent implements OnDestroy {
    @Input() todo;
    subscription: Subscription;

    constructor(private service: TodoService){
        this.subscription = service.todoAdded$.subscribe(
            todo => {
                this.todo = todo;
            }
        );
    }

    remove() {
        this.service.removeTodo(this.todo);
    }

    ngOnDestroy() {
        this.subscription.unsubscribe();
    }
}

这是渲染:

Rendering result

我错过了什么? 我不明白为什么它只是为了第一次出现而不是其他出现。

谢谢!

2 个答案:

答案 0 :(得分:0)

  1. 您应该在NgModule提供程序中包含TodoService。如果在TodoComponent和TodoListComponent中注入TodoService,它们都将获得自己的服务副本。这意味着如果您在TodoComponent中向TodoService添加内容,它将不会显示在TodoListComponent中注入的服务内。

  2. 您应该将订阅服务从构造函数移动到OnInit挂钩。建设者应该是精益的。以下是Angular 2文档所说的内容:

  3.   

    我们不在组件构造函数中获取数据。为什么?因为经验丰富的开发人员同意组件应该便宜且安全。我们不应该担心新组件会在测试中创建或在我们决定显示它之前尝试联系远程服务器。构造函数只需将初始局部变量设置为简单值即可。

         

    当一个组件必须在创建后不久就开始工作时,我们可以指望Angular调用ngOnInit方法来快速启动它。这就是沉重的初始化逻辑所属的地方。

         

    还要记住,在构造之后才会设置指令的数据绑定输入属性。如果我们需要基于这些属性初始化指令,那就是一个问题。当我们的ngOninit运行时,它们将被设置。

答案 1 :(得分:0)

如果你想循环

对象?.name会有所帮助