【问题标题】:Angular2 don't reflect edits to detail record until edits are saved在保存编辑之前,Angular2不会将编辑反映到详细记录
【发布时间】:2016-05-15 11:13:16
【问题描述】:

我有一个父组件和一个子组件。父组件通过属性绑定将对象传递给子组件。

这是一个简单的Master-Child组件通信场景

我的要求是保持父对象中的值,直到子组件在对数据进行一些操作后调用保存事件,同时在父对象发生更改时更新或覆盖子数据。

我用我的实验创造了一个 plunk。它包含 3 个组件。

  1. StudentDetails1 - 值双向更新。
  2. StudentDetails2 - 为要绑定的属性实现了 Setter 和 Getter,但是当父对象更改时,子数据不会更新。(仅在从父构造函数设置时有效。) (Notify child component about changes in Angular2)
  3. StudentDetails3 - 已实现 ngOnChanges,但与 StudentDetails2 存在相同问题

有人可以告诉我使用打字稿在 Angular2 中实现此功能的正确方法吗?还是场景荒谬? :)

http://plnkr.co/edit/SQLRGjaapIslwHZYONY3?p=preview

//Parent component
import {Component} from 'angular2/core'

import {StudentDetails1} from './studentDetails1'
import {StudentDetails2} from './studentDetails2'
import {StudentDetails3} from './studentDetails3'
import {Student} from './student'

@Component({
  selector: 'my-app',
  providers: [],
  template: `
    <h2>Student Master</h2>
    Selected Student <input [(ngModel)]="selectedStudent.name" type="text">
    <student-details1 [student]="selectedStudent" (onCompletion)="onCompletion($event)"></student-details1>
    <student-details2 [student]="selectedStudent" (onCompletion)="onCompletion($event)"></student-details2>
    <student-details3 [student]="selectedStudent" (onCompletion)="onCompletion($event)"></student-details3>
  `,
  directives: [StudentDetails1,StudentDetails2,StudentDetails3]
})
export class App {
  public title = 'Tour of Heroes';
  public selectedStudent: Student;

  constructor() {
      this.selectedStudent = {
          id: 1,
          name: "John Doe"
      }
  }

  onCompletion(modifiedStudent: Student) {
      this.selectedStudent = modifiedStudent;
  }
}

孩子1

import {Component,EventEmitter} from 'angular2/core'
import {Student} from './student'
@Component({
  selector: 'student-details1',
  providers: [],
  template: `
    <h3>Student Details 1</h3>
    Student : <input [(ngModel)]="student.name" type="text">
    <a href="javascript:;" (click)="onSubmit()">Save</a>
  `,
  directives: [],
  inputs:["student"],
  outputs: ['onCompletion']
})
export class StudentDetails1 {
  onCompletion: EventEmitter<Student> = new EventEmitter();

  public student:Student;

  onSubmit(){
      this.student.name += "_Modified";
      this.onCompletion.emit(this.student);
  }
}

孩子2

import {Component,EventEmitter} from 'angular2/core'
import {Student} from './student'
@Component({
  selector: 'student-details2',
  providers: [],
  template: `
    <h3>Student Details 2</h3>
    Student : <input [(ngModel)]="_student.name" type="text">
    <a href="javascript:;" (click)="onSubmit()">Save</a>
  `,
  directives: [],
  inputs:["student"],
  outputs: ['onCompletion']
})
export class StudentDetails2 {
  onCompletion: EventEmitter<Student> = new EventEmitter();

  private _student:Student;
  set student(value:Student){
    this._student = {
      id:value.id,
      name:value.name
    }
  }
  get student(){
    return _student;
  }

  onSubmit(){
      this._student.name += "_Modified";
      this.onCompletion.emit(this._student);
  }
}

孩子3

import {Component,EventEmitter,OnChanges} from 'angular2/core'
import {Student} from './student'
@Component({
  selector: 'student-details3',
  providers: [],
  template: `
    <h3>Student Details 3</h3>
    Student : <input [(ngModel)]="_student.name" type="text">
    <a href="javascript:;" (click)="onSubmit()">Save</a>
  `,
  directives: [],
  inputs:["student"],
  outputs: ['onCompletion']
})
export class StudentDetails3 implements OnChanges {
  onCompletion: EventEmitter<Student> = new EventEmitter();

  private _student:Student;
  public student:Student;

  onSubmit(){
      this._student.name += "_Modified";
      this.onCompletion.emit(this._student);
  }

  ngOnChanges(){
    this._student = {
      id:this.student.id,
      name:this.student.name
    }
  }
}

内存

【问题讨论】:

  • 信息量很大,但我并不完全清楚您真正想知道什么。
  • @GünterZöchbauer 你能试试运行 plunk 吗?仅当子组件单击“保存”时,我才需要更新父数据。同时,数据应该在父对象更新时传递给子组件。

标签: typescript angular


【解决方案1】:

Hierarchical Injectors 开发指南中提供了“编辑详细记录”问题的通用(优雅)解决方案。

通用EditItem&lt;T&gt; 类和通用RestoreService&lt;T&gt; 服务用于帮助编辑详细记录。除非用户保存更改,否则更改不会反映到父级(即应用程序的其余部分)。

【讨论】:

  • 刚到 (5. Forms) 开发人员指南时,我遇到了这个疑问。很长很长的路要走。这正是我想到的场景。由于这是任何应用程序中非常常见的场景,难道这不应该是 Angular2 的内置功能,而不是每个人都实现相同的泛型类并经历跟踪项目状态的麻烦吗?只是大声思考。
  • @rmchndrng,好吧,不包括它的一个原因是:您可能希望向一个或两个通用类添加更多功能。有人可能会争辩说,这种类型的功能超出了框架应该提供的范围。而且我相信泛型是 TypeScript 的特性(不是 ES2015)。
【解决方案2】:

我会这样做

http://plnkr.co/edit/bOyWbU3bznFYfUFpGYOM?p=preview (src/studentDetails1.ts)

拆分下游绑定和上游绑定

Student : <input [ngModel]="student.name" (ngModelChange)="_student=$event" type="text">
export class StudentDetails1 {
  onCompletion: EventEmitter<Student> = new EventEmitter();

  public student:Student;
  private _student:Student;

  onSubmit(){
      // update upstream model only on submit
      this.student.name = this._student + "_Modified";
      this.onCompletion.emit(this.student);
  }
}

【讨论】:

  • 完美。非常感谢。
  • 如果我错了,请纠正我,您刚刚所做的是与 DOM 相交 -> 组件更改并将其分配给私有对象。这是解决这种情况的常用方法吗?
  • 这取决于您还有什么其他要求。您还可以将ngOnInit() 中的@Input() student:Student; 中的值复制到this._student,绑定到[(ngModel)]="_student",然后像演示的那样在上游提交更新。总有很多方法可以实现某事。对于手头的任务,我演示的似乎是最简单的。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2010-11-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多