Reputation: 1487
I have decided to create component like separate widget, e.g. parent passes config to it and component fetches data (the parent does not need data from the child). But there some cases, e.g some update in parent, which can affect displayed data. So I would like kind of say to child: refetch the data, while config remaining the same. But this won't cause $onChanges
callback to fire, as link to config object is the same, so I fixed it in a hacky way:
vm.childConfig = _.assign({}, vm.childConfig);
This works fine, but ugly, as for me. Are there any better solutions for it? (creating $watch, emitting events seem to be even worse solution)
Some example code:
<parent-component>
<child-component config="childConfig"></child-component>
</parent-component>
JS:
function ParentComponentController () {
vm.childConfig = {show: true, ...}
vm.onItemDelete = function () {
vm.childConfig = _.assign({}, vm.childConfig); // I want to call `fetchData` so I force child $onChanges to fire.
}
}
function ChildComponentController () {
vm.$onInit = function () {
fetchData()
}
vm.$onChanges = function () {
// will not fire if will not change the config object reference
fetchData(changes)
}
}
So I want something like force child to call $onChanges
P.S. I don't like the idea for the child to be dumb component (parent passes fetched data to it), of course it will fix this issue, but the data is only needed in the child, and it will make parent component even fatter.
Upvotes: 2
Views: 74
Reputation: 12813
Is this the kind of thing you mean?
JS
angular.module("app")
.component(
"ChildComponent",
{
controller: ChildComponentCtrl,
bindings: {
config: "<",
update: "<"
}
}
);
function ChildComponent () {
var init = false;
function init() {
// Set up config
init = true;
}
function update() {
// config remains the same but do something else
}
this.$onChanges = function () {
if (angular.isDefined(this.config) && !init) {
init();
}
else if (angular.isDefined(this.update)) {
update();
}
};
}
Markup
<parent-component>
<child-component config="childConfig" update="update"></child-component>
</parent-component>
Edit - To make sure update works more than once do the following:
ChildComponent
this.$onChanges = function () {
if (angular.isDefined(this.config) && !init) {
init();
}
else if (angular.isDefined(this.update) && update) {
update();
}
};
ParentComponent
function doUpdate() {
this.update = true;
// Rest update so that it works next time
$timeout(function () {
this.update = false;
});
}
Upvotes: 1