父级没有触发Angular 2 @Output

时间:2016-07-09 16:51:38

标签: angularjs angular

我有一个简单的待办事项应用程序,显示待办事项列表。单击其中一个时,它会显示更多详细信息并在行上设置选定状态。在新的详细信息窗口中,我添加了一个关闭按钮。单击时,它应关闭详细信息窗口并删除待办事项列表中的选定状态。它已成功关闭todo窗口,但未重置todo列表中的状态。

列表:

$value = $_GET["value"];
//here you makes your query
$query = mysqli_query(your_connection(),"select * from your_table where your_column_name = ".$value);
$array = @mysqli_fetch_array($query);
if($array != ''){
  $introducerName = $array["introducerName"];
echo "$('#Introducerame').val('".$introducerName."')";
}

list.html

@Component({
    ...
    directives: [[TodoDetailComponent]],
    ...
})

export class ListComponent implements OnInit {
    public todos: Todo[];
    title = 'List of Todos';
    selectedTodo: Todo;
    newTodo: string;

    constructor(private todoService: TodoService) {

    }
    ...

    todoClosed(event) {
        console.log(event);
        this.selectedTodo = null;
        console.log('here');
    }
}

细节

    <div class="row">
    <div class="col-md-12">
        <div class="col-md-6">
            <div class="panel panel-default">
                <div class="panel-heading">
                    <h3 class="panel-title">{{title}}</h3>
                </div>
                <div class="panel-body">
                    <input [(ngModel)]="newTodo" placeholder="New Todo"/>
                    <a class="btn btn-success" (click)="addTodo()">Add</a>
                    <div class="list-group">
                        <div *ngFor="let todo of todos"
                           (click)="onSelect(todo)"
                           (todoClosed)="todoClosed($event)"
                           [class.active]="todo === selectedTodo"
                           [class.list-group-item-success]="todo.completed"
                           class="list-group-item">
                            <input type="checkbox" [(ngModel)]="todo.completed" />
                            {{todo.task}}
                            <span class="badge glyphicon glyphicon-arrow-right"> </span>
                        </div>
                    </div>
                </div>
            </div>
        </div>
        <div class="col-md-6">
            <todo-detail [todo]="selectedTodo"></todo-detail>
        </div>
    </div>
</div>

detail.html

@Component({
    selector: 'todo-detail',
    templateUrl: 'app/todo/templates/detail.html'
})

export class TodoDetailComponent {
    @Input() todo: Todo;
    @Output() public todoClosed: EventEmitter = new EventEmitter();

    closeTodo(todo: Todo) {
        this.todoClosed.emit({
            value: todo
        });
        this.todo = null;
    }
}

app.routes

<div class="panel panel-default" *ngIf="todo">
    <div class="panel-heading">
        <h3 class="pull-left panel-title">
            <label>id: </label>{{todo.id}}
            <span class="success glyphicon glyphicon-check" *ngIf="todo.completed"> </span>
        </h3>
        <span class="pull-right glyphicon glyphicon-minus" (click)="closeTodo(todo)"> </span>
        <div class="clearfix"></div>
    </div>
    <div class="panel-body">
        <label>name: </label>
        <input [(ngModel)]="todo.task" placeholder="name"/>
    </div>
</div>

app.component

import { provideRouter, RouterConfig }  from '@angular/router';
import { ListComponent } from './todo/component/list.component';

const routes: RouterConfig = [
    {
        path: 'todos',
        component: ListComponent
    },
    {
        path: '',
        redirectTo: '/todos',
        pathMatch: 'full'
    }
];

export const APP_ROUTER_PROVIDERS = [
    provideRouter(routes)
];

main.ts

import { Component, OnInit } from '@angular/core';
import {ListComponent} from "../../todo/component/list.component";
import {TodoService} from "../../todo/service/todo.service";
import { ROUTER_DIRECTIVES } from '@angular/router';


@Component({
    selector: 'my-app',
    template: `
        <h1>{{title}}</h1>
        <router-outlet></router-outlet>
    `,
    directives: [[ListComponent, ROUTER_DIRECTIVES]],
    providers: [TodoService]
})

export class AppComponent {
    title: 'test'
}

2 个答案:

答案 0 :(得分:0)

有一个错字

closeTodo(todo: Todo) {
    this.todoClosed.emit({
        value: todo // todo instead of Todo
    });
    this.todo = null;
}

<强>更新

您正在从TodoDetailComponent发出该事件,但会收听一些未发出该事件的<div *ngFor="let todo of todos" ... (todoClosed)="todoClosed($event)" ...>

答案 1 :(得分:0)

我找到了解决方案。如果我将事件移动到服务中,我可以从我的两个组件订阅该事件。

服务

import { Injectable, Output, EventEmitter } from '@angular/core';
import { Todo } from '../model/todo';
import { TODOS } from './mock-todos';

@Injectable()
export class TodoService {
    @Output() public todoClosed: EventEmitter = new EventEmitter();
    ...
    closeTodo(todo: Todo) {
        this.todoClosed.emit({
            value: todo
        });
    }
}

两个组件构造函数

constructor(private todoService: TodoService) {
        todoService.todoClosed.subscribe(
            todo => this.closeTodo(todo)
        )
    }