Advertisement
Guest User

Untitled

a guest
Jun 30th, 2016
74
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.49 KB | None | 0 0
  1. import * as React from 'react'
  2.  
  3. export interface IPropertyChangedListener{
  4. (subject: any, propertyName: string): void
  5. }
  6.  
  7. const eventsMap = new WeakMap<any, IPropertyChangedListener[]>()
  8.  
  9. export function propertyChanged(subject: any, propertyName: string){
  10. const listeners = eventsMap.has(subject) ? eventsMap.get(subject) : []
  11.  
  12. for(var i = 0; i < listeners.length; i++){
  13. listeners[i](subject, propertyName)
  14. }
  15. }
  16.  
  17. export function onPropertyChanged(subject: any, changedCallback: IPropertyChangedListener){
  18. var isSubscribed = true
  19.  
  20. const listeners = eventsMap.has(subject) ? eventsMap.get(subject) : []
  21. eventsMap.set(subject, listeners.concat([changedCallback]))
  22.  
  23. return () => {
  24. if(!isSubscribed){
  25. return
  26. }
  27.  
  28. isSubscribed = false
  29.  
  30. const listeners = eventsMap.has(subject) ? eventsMap.get(subject) : []
  31. eventsMap.set(subject, listeners.splice(listeners.indexOf(changedCallback), 1))
  32. }
  33. }
  34.  
  35. export interface IDataContextProps{
  36. source: any
  37. }
  38.  
  39. class DataContext extends React.Component<IDataContextProps, any>{
  40. getChildContext(){
  41. return {
  42. context: this.props.source
  43. }
  44. }
  45.  
  46. render() {
  47. return React.Children.only(this.props.children)
  48. }
  49. }
  50.  
  51. (DataContext as React.ComponentClass<IDataContextProps>).childContextTypes = {
  52. context: React.PropTypes.any
  53. }
  54.  
  55. export interface IBinding{
  56. path: string
  57. property: string
  58. sourceEvent: string
  59. valueFromEvent: (e: any) => any
  60. }
  61.  
  62. export interface IBindingProps<TProps>{
  63. component: React.ComponentClass<TProps>
  64. bindings: IBinding[]
  65. }
  66.  
  67. class Binding<TProps> extends React.Component<IBindingProps<TProps> & TProps, any>{
  68. dispose: () => void = null
  69.  
  70. componentWillMount(){
  71. this.dispose = onPropertyChanged((<any> this.context).source, this.forceUpdate.bind(this))
  72. }
  73.  
  74. componentWillUnmount(){
  75. if(this.dispose){
  76. this.dispose()
  77. }
  78. }
  79.  
  80. render() {
  81. var newProps = this.props
  82. for(var i = 0; i < this.props.bindings.length; i++){
  83. const binding = this.props.bindings[i]
  84. newProps[binding.property] = (<any> this.context).source[binding.path]
  85. newProps[binding.sourceEvent] = (e) => (<any> this.context).source[binding.path] = binding.valueFromEvent(e)
  86. }
  87. return React.createElement(this.props.component, newProps, this.props.children)
  88. }
  89. }
  90.  
  91. (Binding as React.ComponentClass<any>).contextTypes = {
  92. context: React.PropTypes.any
  93. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement