Angular 2无国籍或有状态?

时间:2017-02-25 11:24:43

标签: angular stateless stateful

所以这是我的问题。我在这里有这个组件,它编辑一个通过输入传递的联系人。当我在输入文本中更改某些内容(双向数据绑定),然后在点击保存并路由到另一个组件(显示所有联系人列表)时“保存”时,此代码可以正常工作并更改联系参数。

import {Component} from 'angular2/core';
import {Contact} from "./contact";
import {Router} from "angular2/src/router/router";
import {OnInit} from "angular2/src/core/linker/interfaces";
import {ContactService} from "./contacts.service";

@Component({
    selector:'editor',
    template:`
    <div class='editor'>
        <label>Edit name : </label><input type="text" [(ngModel)]="contact.name">
        <br>
        <label>Edit email : </label><input type="text" [(ngModel)]="contact.email">
        <br>
        <label>Edit phone number: </label><input type="text" [(ngModel)]="contact.phone">
        <br>
        <div class="description">
        Description: 
        <br>
        <textarea rows="4" cols="50" [(ngModel)]="contact.description"></textarea>
        </div>
        <br>
        <input type="button" (click)="onCreateContact()" class="button" value="Save Changes"/>
    </div>
`,
    inputs:["contact"],
    styles:[
      `
        label {
          display: inline-block;
          width: 145px;
          border-left: 3px solid #006ec3;
          padding-left: 8px;
          padding-bottom: 8px;
        }
        .description{

          border-left: 3px solid #006ec3;
          padding-left: 8px;
          padding-bottom: 8px;
        }
      `
    ]
})

export class ContactEditorComponent implements OnInit{

    public contact:Contact;

    constructor(private router:Router){

    }

    onCreateContact(){
      this.router.navigate(['Contacts']);
    }

}

现在,如果我通过添加一个temp:Contact变量来改变我的类,该变量将我的联系人克隆起来,更改临时变量然后将其克隆到联系人对象,当我点击时,更改不再保存按钮。

@Component({
    selector:'editor',
    template:`
    <div class='editor'>
        <label>Edit name : </label><input type="text" [(ngModel)]="temp.name">
        <br>
        <label>Edit email : </label><input type="text" [(ngModel)]="temp.email">
        <br>
        <label>Edit phone number: </label><input type="text" [(ngModel)]="temp.phone">
        <br>
        <div class="description">
        Description: 
        <br>
        <textarea rows="4" cols="50" [(ngModel)]="temp.description"></textarea>
        </div>
        <br>
        <input type="button" (click)="onCreateContact()" class="button" value="Save Changes"/>
    </div>
`,
    inputs:["contact"],
    styles:[
      `
        label {
          display: inline-block;
          width: 145px;
          border-left: 3px solid #006ec3;
          padding-left: 8px;
          padding-bottom: 8px;
        }
        .description{

          border-left: 3px solid #006ec3;
          padding-left: 8px;
          padding-bottom: 8px;
        }
      `
    ]
    }) 

export class ContactEditorComponent implements OnInit{

    public contact:Contact;
    public temp:Contact;
    constructor(private router:Router){

    }

    onCreateContact(){
      this.contact = (<any>Object).assign({}, this.temp);
      console.log(this.contact.name);
      this.router.navigate(['Contacts']);
    }

  ngOnInit(){
      this.temp = (<any>Object).assign({}, this.contact);
  }
}

我的所有联系人都保存在另一个包含Const联系人数组的文件中,并通过contact.service访问。

1 个答案:

答案 0 :(得分:1)

这与Angular无关,而与JavaScript有关。

以下是一个例子:

const parent = {};
parent.contact = {id: 'c1'};
const child = {};
child.contact = parent.contact;

现在,child.contactparent.contact都是对同一对象的引用。所以

child.contact.id = 'c2';
console.log(parent.contact.id);

将打印'c2'。

这就是你在第一个例子中所做的。

现在你的第二个例子是:

const parent = {};
parent.contact = {id: 'c1'};
const child = {};
child.contact = parent.contact;
child.temp = {id: 'c1'}; // clone of child.contact

现在,child.temp引用了一个新对象,该对象与child.contactparent.contact不同(副本)。

然后你要修改temp联系人的ID:

child.temp.id = 'c2';

然后,在保存时,你正在做

child.contact = {id: 'c2'}; // clone of child.temp

所以现在你有3个不同的对象:一个是parent.contact的引用,还有'c1'作为id,child.tempparent.contact的修改后的副本,并且child.contact是child.temp的另一个副本。

如果要更改child.contactparent.contact引用的对象的ID值,则需要执行

child.contact.id = temp.contact.id;

或者,在您的示例中:

Object.assign(child.contact, temp.contact);