Reputation: 24567
I've got a simple contactList
component, which has 2 bindings: contacts
and onRemove
.
contacts
is just an array of contacts to displayonRemove
is a callback functionapp
.component('contactList', {
template:
`<div ng-repeat="c in $ctrl.contacts">
{{c.name}}
<div ng-click="$ctrl.onRemove({contact: c})">Remove</div>
</div>`,
bindings: {
contacts: '<',
onRemove: '&'
},
controller: function() {}
})
I use this component multiple times within my app. And the onRemove
callback can behave differently, depending on where the contactList
component is getting used. Example:
contactMainView
(= component) displays a search bar and the resulting list of contacts using the contactList
component. onRemove
will delete the contact from the database.
groupMembersView
displays all contacts belonging to the given group using the contactList
component. Here it shouldn't be possible to remove a contact, though onRemove
will not be set.
First I thought, that I could use an ng-if="$ctrl.onRemove"
but that doesn't work, because onRemove
is never undefined
within contactList
component. console.log(this.onRemove)
always prints: function(locals) { return parentGet(scope, locals); }
Of course I could use another showRemove: '@'
binding, but that doesn't look DRY to me.
Do you have any idea or some better solution to get things done?
Upvotes: 14
Views: 3689
Reputation: 198
another option is to define the callback as optional by adding a question mark in the binding definition:
onRemove: '&?'
text from the documentation: All 4 kinds of bindings (@, =, <, and &) can be made optional by adding ? to the expression. The marker must come after the mode and before the attribute name. See the Invalid Isolate Scope Definition error for definition examples.
Upvotes: 0
Reputation: 1445
Execute the function onRemove on component allow to get if a function was passed in parameter. So you can use ng-if="$ctrl.onRemove()"
component('contactList', {
template:
`<div ng-repeat="c in $ctrl.contacts">
{{c.name}}
<div ng-click="$ctrl.onRemove()({contact: c})" ng-if="$ctrl.onRemove()">Remove</div>
</div>`,
bindings: {
contacts: '<',
onRemove: '&'
},
controller: function() {
console.log(this.onRemove);
console.log(this.onRemove());
}
})
Upvotes: 0
Reputation: 16876
The simplest way would to check if the attribute is defined. In your controller inject $attrs
and then you can do:
if( $attrs.onRemove ) { //Do something }
Using the &
binding angular will wrap the function in order to keep references to the original $scope
of the passed method, even if is not defined.
Upvotes: 22