Angular 4: Как просмотреть объект для изменений?
ETA: Я знаю, что есть различные способы посмотреть мою форму изменений. Это не то, что я пытаюсь сделать. Как говорится в названии, я спрашиваю, как следить за изменениями в объекте. Приложение, показанное ниже, предназначено только для иллюстрации. Пожалуйста, ответьте на вопрос, который я задал. Спасибо!
У меня есть это простое приложение:
import { Component, OnInit } from '@angular/core';
export class Customer {
firstName: string;
favoriteColor: string;
}
@Component({
selector: 'my-app',
template: `
<div *ngIf="customer">
<input type="text" [(ngModel)]="customer.firstName">
<input type="text" [(ngModel)]="customer.favoriteColor">
</div>
`
})
export class AppComponent implements OnInit {
private customer: Customer;
ngOnInit(): void {
this.customer = new Customer();
// TODO: how can I register a callback that will run whenever
// any property of this.customer has been changed?
}
}
Обратите внимание на TODO. Мне нужно зарегистрировать обратный вызов, который будет выполняться всякий раз, когда будет изменено любое свойство this.customer
.
Я не могу использовать ngChange на входах. Мне нужно подписаться непосредственно на изменения в модели. Причины относятся к моему прецеденту и не стоит здесь входить. Просто поверьте мне, что это не вариант.
Возможно ли это? Я сделал много Googling, но я придумал сухую.
Ответы
Ответ 1
Angular обычно использует встроенный в конструктор класс KeyValueDiffers.
Для вашего случая это может выглядеть так:
import { KeyValueChanges, KeyValueDiffer, KeyValueDiffers } from '@angular/core';
export class Customer {
firstName: string;
favoriteColor: string;
}
@Component({
selector: 'my-app',
templateUrl: './app.component.html'
})
export class AppComponent {
private customerDiffer: KeyValueDiffer<string, any>;
private customer: Customer;
constructor(private differs: KeyValueDiffers) {}
ngOnInit(): void {
this.customer = new Customer();
this.customerDiffer = this.differs.find(this.customer).create();
}
customerChanged(changes: KeyValueChanges<string, any>) {
console.log('changes');
/* If you want to see details then use
changes.forEachRemovedItem((record) => ...);
changes.forEachAddedItem((record) => ...);
changes.forEachChangedItem((record) => ...);
*/
}
ngDoCheck(): void {
const changes = this.customerDiffer.diff(this.customer);
if (changes) {
this.customerChanged(changes);
}
}
}
Пример Stackblitz
Еще один вариант - использовать setter для свойств, которые вы хотите проверить.
Смотрите также
Ответ 2
Мне нужно подписаться непосредственно на изменения в модели.
Затем вам нужно прослушать изменения модели с помощью ngModelChange
Шаблон:
<input type="text" (ngModelChange)="doSomething($event)" [ngModel]="customer.firstName">
Класс:
doSomething(event) {
console.log(event); // logs model value
}
DEMO
Ответ 3
Вы не можете просматривать изменения в объекте. Его не angular 1 здесь нет наблюдателей. Другое решение будет через наблюдаемые.
использовать форму
<form #f="ngForm">
<input type="text" name="firstName" [(ngModel)]="customer.firstName">
<input type="text" name="favoriteColor" [(ngModel)]="customer.favoriteColor">
</form>
в коде
@ViewChild('f') f;
ngAfterViewInit() {
this.f.form.valueChanges.subscribe((change) => {
console.log(change)
})
}
Ответ 4
Вы можете использовать настраиваемые сеттеры для запуска обратного вызова:
class Customer {
private _firstName: string
get firstName(): string {
return this._firstName
}
set firstName(firstName: string) {
this.valueChanged(this._firstName, firstName)
this._firstName = firstName
}
private _lastName: string
get lastName(): string {
return this._lastName
}
set lastName(lastName: string) {
this.valueChanged(this._lastName, lastName)
this._lastName = lastName
}
valueChanged: (oldVal, newVal) => void
constructor (valueChanged?: (oldVal, newVal) => void) {
// return an empty function if no callback was provided in case you don't need
// one or want to assign it later
this.valueChanged = valueChanged || (() => {})
}
}
Затем просто назначьте обратный вызов при создании объекта:
this.customer = new Customer((oldVal, newVal) => console.log(oldVal, newVal))
// or
this.customer = new Customer()
this.customer.valueChanged = (oldVal, newVal) => console.log(oldVal, newVal)
Ответ 5
посетите https://github.com/cartant/rxjs-observe. основывается на rxjs и прокси.
import { observe } from "rxjs-observe";
const instance = { name: "Alice" };
const { observables, proxy } = observe(instance);
observables.name.subscribe(value => console.log(name));
proxy.name = "Bob";
Ответ 6
Вы можете увидеть эту статью, может быть, это поможет.
constructor(private ref: ChangeDetectorRef) {}
removeSomthing(){
this.items.split(idx, 1);
// run manually watcher
this.ref.detectChanges();
}