pasar - page title angular 4
¿Cómo llamar a la función cada vez que el modelo cambia en angular 2? (4)
Tengo un componente de selección personalizado que establece el modelo al hacer clic en un elemento li
, pero como lo llamo manualmente.modeloCambio.next this.modelChange.next(this.model)
cada vez que cambio el modelo es bastante complicado y repetible, lo que deseo evitar.
Entonces, mi pregunta es si hay algo similar a $scope.$watch
dónde puedo ver si un valor cambia y luego llame a this.modelChange.next(this.model)
cada vez que suceda.
He estado leyendo sobre Observables
pero no puedo entender cómo se supone que se debe usar esto solo para un valor simple, ya que todos los ejemplos que veo son con solicitudes asíncronas a api: s externos.
¿Seguramente debe haber una forma más sencilla de lograr esto?
(No es que no pueda usar ngModelChanges
porque no estoy usando una entrada para esto).
import {Component, Input, Output, EventEmitter, OnInit, OnChanges} from ''angular2/core'';
@Component({
selector: ''form-select'',
templateUrl: ''./app/assets/scripts/modules/form-controls/form-select/form-select.component.html'',
styleUrls: [''./app/assets/scripts/modules/form-controls/form-select/form-select.component.css''],
inputs: [
''options'',
''callback'',
''model'',
''label''
]
})
export class FormSelectComponent implements OnInit, OnChanges {
@Input() model: any;
@Output() modelChange: EventEmitter = new EventEmitter();
public isOpen: boolean = false;
ngOnInit() {
if (!this.model) {
this.model = {};
}
for (var option of this.options) {
if (option.model == (this.model.model || this.model)) {
this.model = option;
}
}
}
ngOnChanges(changes: {[model: any]: SimpleChange}) {
console.log(changes);
this.modelChange.next(changes[''model''].currentValue);
}
toggle() {
this.isOpen = !this.isOpen;
}
close() {
this.isOpen = false;
}
select(option, callback) {
this.model = option;
this.close();
callback ? callback() : false;
}
isSelected(option) {
return option.model === this.model.model;
}
}
Edición: intenté usar ngOnChanges
(ver el código actualizado más arriba), pero solo se ejecuta una vez en la inicialización y no detecta cambios. ¿Hay algo mal?
Entonces, mi pregunta es si hay algo similar a $ scope. $ Mire dónde puedo ver si el valor del
model
propiedad de entrada cambia
Si el model
es un tipo primitivo de JavaScript (Número, Cadena, Booleano), entonces puede implementar ngOnChanges()
para que se le notifiquen los cambios. Ver ejemplo de libro de cocina y documento del ciclo de vida, sección OnChanges .
Otra opción es usar un setter y un getter. Ver ejemplo de libro de cocina .
Si el model
es un tipo de referencia de JavaScript (Array, Objeto, Fecha, etc.), entonces la forma en que detecte los cambios depende de cómo cambie el modelo:
- Si la referencia del modelo cambia (es decir, si asigna una nueva matriz, un nuevo objeto, etc.), puede implementar
ngOnChanges()
para que se le notifiquen los cambios, al igual que para los tipos primitivos. - Sin embargo, si la referencia del modelo no cambia, pero alguna propiedad del modelo cambia (p. Ej., El valor de un elemento de la matriz cambia o si se agrega o elimina un elemento de la matriz, o si cambia el valor de una propiedad del objeto), puede implementar
ngDoCheck()
para implementar su propia lógica de detección de cambios.
Ver doc. Del ciclo de vida, sección DoCheck .
Puede hacer que el model
un getter / setter o implementar OnChanges agregando un ngOnChanges(changes) {}
que se @Input()
cada vez que @Input()
un valor @Input()
.
El ejemplo ngOnChanges()
de los documentos (vinculado arriba):
@Component({
selector: ''my-cmp'',
template: `<p>myProp = {{myProp}}</p>`
})
class MyComponent implements OnChanges {
@Input() myProp: any;
ngOnChanges(changes: {[propName: string]: SimpleChange}) {
console.log(''ngOnChanges - myProp = '' + changes[''myProp''].currentValue);
}
}
@Component({
selector: ''app'',
template: `
<button (click)="value = value + 1">Change MyComponent</button>
<my-cmp [my-prop]="value"></my-cmp>`,
directives: [MyComponent]
})
export class App {
value = 0;
}
bootstrap(App).catch(err => console.error(err));
Actualizar
Si el estado interno del model
cambia pero no el model
sí (instancia del model
diferente), entonces la detección de cambios no lo reconoce. Debe implementar su propio mecanismo para notificar el código interesado, como usar un model
Observable
en el que se emita un evento en el cambio al que se pueda suscribir su componente.
Además, solo se llama a ngOnChanges()
cuando se cambia el model
por el enlace de datos (cuando someFieldInParent
ha cambiado en <my-comp [model]="someFieldInParent">
y Angular pasa el nuevo valor al model
en MyComponent
.
return option.model === this.model.model;
no hace que se ngOnChanges()
. Para que esto funcione, el enfoque getter / setter es un mejor ajuste.
Si selecciona un componente personalizado internamente usa el (los) ingreso (s) de formulario, aprovecharía el evento ngModelChange en él / ellos:
<select [ngModel]="..." (ngModelUpdate)="triggerUpdate($event)">…</select>
o los cambios de valores observables de los controles correspondientes si los hubiera. En la plantilla:
<select [ngFormControl]="myForm.controls.selectCtrl">…</select>
En el componente:
myForm.controls.selectCtrl.valueChanges.subscribe(newValue => {
(...)
});
ngAfterViewChecked es un mejor método de ciclo de vida, ya que se invoca después de que se procesa el DOM y se puede realizar cualquier manipulación aquí.
https://.com/a/35493028/6522875