https://github.com/loopmode/bind
Helper for binding the scope of class methods
https://github.com/loopmode/bind
Last synced: about 1 year ago
JSON representation
Helper for binding the scope of class methods
- Host: GitHub
- URL: https://github.com/loopmode/bind
- Owner: loopmode
- Created: 2018-12-06T09:19:30.000Z (over 7 years ago)
- Default Branch: master
- Last Pushed: 2020-02-03T12:56:32.000Z (about 6 years ago)
- Last Synced: 2025-02-08T18:36:50.012Z (about 1 year ago)
- Language: TypeScript
- Size: 271 KB
- Stars: 0
- Watchers: 2
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
Awesome Lists containing this project
README
# @loopmode/bind
A scope binding mechanism for javascript classes.
## Default matcher
Out of the box, the function will bind all methods that have a name starting with `on` followed by uppercase character, or `handle` followed by either uppercase character or underscore.
You are encouraged to use a naming convention like that (e.g. `handleClick`), because then you don't need to pass any arguments but the class instance itself:
```javascript
import bind from '@loopmode/bind';
export class Demo {
constructor() {
bind(this);
window.addEventListener('click', this.handleClick);
}
handleClick(event) {
console.log('handleClick', this, event);
}
}
```
## Special matchers
- `*` bind all methods, regardless of their name
- A matcher can be a function that receives the function name and returns a boolean
## Custom matchers
You can also pass additional arguments to specify custom matchers:
```javascript
import bind from '@loopmode/bind';
export class Demo {
constructor() {
bind(this, /^handle/, 'init');
}
init() {
window.addEventListener('click', this.handleClick);
window.addEventListener('change', this.handleChange);
}
destroy() {
window.removeEventListener('click', this.handleClick);
window.removeEventListener('change', this.handleChange);
}
handleClick(event) {
console.log('handleClick', this, event);
}
handleChange(event) {
console.log('handleChange', this, event);
}
}
const demo - new Demo();
document.addEventListener('DOMContentLoaded', demo.init)
```
Some more examples:
```javascript
bind(this, /^on/); // match `onClick`, `onChange` etc, using RegExp object
bind(this, '^on'); // same as before, but with string regex
bind(this, 'on'); // string matcher, will match both `onClick` and e.g. `createBaboon`
bind(this, 'on$'); // Will match `createBaboon` but not `onClick`
bind(this, /^handle/, /^on/); // Will match all methods starting with `handle` or `on`, multiple arguments
bind(this, [/^handle/, /^on/]); // Same as before, but with a single array as argument
bind(this, [/^handle/, 'renderConfirmDialog']); // Typical real-world-case, match handlers but also some specific render method that gets injected into a child
```
## Custom wrapper
In case you do have a naming convention, but it's not `handle*`, you should create your own module with a wrapper function that provides the appropriate matcher, and use that - without passing extra arguments.
For example, if you typically use `onEvent` rather than `handleEvent`, your own `bind` module might export this wrapper function:
```javascript
import bind from '@loopmode/bind';
export default instance => bind(instance, /^on/);
```
## React components
You will not run into troubles with e.g. React components - lifecycle methods are not bound unless you defined an explicit matcher for that (e.g. `render` or `/^componentDid/` etc).
```javascript
import React from 'react';
import bind from '@loopmode/bind';
export class bind extends React.Component {
state = {
clickCount: 0
};
constructor(props) {
super(props);
bind(this);
}
render() {
return click me;
}
handleClick(event) {
this.setState({ clickCount: this.state.clickCount + 1 });
}
}
```