Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- import * as React from 'react'
- export interface IPropertyChangedListener{
- (subject: any, propertyName: string): void
- }
- const eventsMap = new WeakMap<any, IPropertyChangedListener[]>()
- export function propertyChanged(subject: any, propertyName: string){
- const listeners = eventsMap.has(subject) ? eventsMap.get(subject) : []
- for(var i = 0; i < listeners.length; i++){
- listeners[i](subject, propertyName)
- }
- }
- export function onPropertyChanged(subject: any, changedCallback: IPropertyChangedListener){
- var isSubscribed = true
- const listeners = eventsMap.has(subject) ? eventsMap.get(subject) : []
- eventsMap.set(subject, listeners.concat([changedCallback]))
- return () => {
- if(!isSubscribed){
- return
- }
- isSubscribed = false
- const listeners = eventsMap.has(subject) ? eventsMap.get(subject) : []
- eventsMap.set(subject, listeners.splice(listeners.indexOf(changedCallback), 1))
- }
- }
- export interface IDataContextProps{
- source: any
- }
- class DataContext extends React.Component<IDataContextProps, any>{
- getChildContext(){
- return {
- context: this.props.source
- }
- }
- render() {
- return React.Children.only(this.props.children)
- }
- }
- (DataContext as React.ComponentClass<IDataContextProps>).childContextTypes = {
- context: React.PropTypes.any
- }
- export interface IBinding{
- path: string
- property: string
- sourceEvent: string
- valueFromEvent: (e: any) => any
- }
- export interface IBindingProps<TProps>{
- component: React.ComponentClass<TProps>
- bindings: IBinding[]
- }
- class Binding<TProps> extends React.Component<IBindingProps<TProps> & TProps, any>{
- dispose: () => void = null
- componentWillMount(){
- this.dispose = onPropertyChanged((<any> this.context).source, this.forceUpdate.bind(this))
- }
- componentWillUnmount(){
- if(this.dispose){
- this.dispose()
- }
- }
- render() {
- var newProps = this.props
- for(var i = 0; i < this.props.bindings.length; i++){
- const binding = this.props.bindings[i]
- newProps[binding.property] = (<any> this.context).source[binding.path]
- newProps[binding.sourceEvent] = (e) => (<any> this.context).source[binding.path] = binding.valueFromEvent(e)
- }
- return React.createElement(this.props.component, newProps, this.props.children)
- }
- }
- (Binding as React.ComponentClass<any>).contextTypes = {
- context: React.PropTypes.any
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement