В angular2, как получить onChanges для свойств, измененных на объект, отправленный для @Input
У меня есть директива, и на ней есть @Input
, который принимает класс.
@Directive({selector: 'my-directive'})
@View({directives: [CORE_DIRECTIVES]})
export class MyDirective {
@Input() inputSettings : SettingsClass;
@Input() count : number;
onChanges(map) {
console.log('onChanges');
}
}
Директива используется в html:
...
<my-directive [input-settings]="settings" [count]="settings.count"></my-directive>
...
Если параметр settings.count изменен, загорится onChanges
. Если какое-либо другое свойство в классе настроек изменяется, оно не срабатывает.
Как определить, есть ли какое-либо изменение в настройках?
Ответы
Ответ 1
Angular заметит только, если объект был изменен на другой объект (т.е. ссылка на объект изменена), поэтому ngOnChanges()
не может использоваться для решения вашей проблемы. Подробнее см. сообщение в блоге Виктора Савки.
Вы можете реализовать метод ngDoCheck()
в своем классе MyDirective. Этот крючок жизненного цикла называется "каждый раз, когда проверяются свойства ввода компонента или директивы". Используйте его для расширения обнаружения изменений путем выполнения специальной проверки. "
Чтобы реализовать свой собственный метод проверки, вам сначала нужно реализовать метод .equals()
в классе SettingsClass
, чтобы затем вы могли написать код в виде ngDoCheck()
:
ngDoCheck() {
if(!this.inputSettings.equals(this.previousInputSettings)) {
// inputSettings changed
// some logic here to react to the change
this.previousInputSettings = this.inputSettings;
}
}
Ответ 2
Другое решение, которое полезно, когда у вас нет контроля над объектом, который вы передаете компоненту, - это использование ViewChild и прямой вызов метода для обновления объекта:
В дочерний компонент добавьте функцию, например:
public updateSettings(obj: SettingsClass) {
this.inputSettings = obj;
}
А в родительском компоненте вызовите функцию updateSettings:
@Component({
selector: 'app-mycomponnent',
templateUrl: './my.component.html',
styleUrls: ['./my.component.css']
})
export class PlayComponent implements OnInit {
@ViewChild(MyDirectiveComponent,{static: false}) mydirective;
elsewhereinthecode() {
// When you need to update call :
mydirective.updateSettings(settingsObject);
}
}
Ответ 3
В вашем html вы не можете использовать CamelCase, измените его на
<my-directive [input-settings]="settings" [count]="settings.count"></my-directive>