Skip to content

Commit

Permalink
feat: support for this.parentComponent, see #52
Browse files Browse the repository at this point in the history
  • Loading branch information
harttle committed May 14, 2020
1 parent 5879aaa commit 480105c
Show file tree
Hide file tree
Showing 5 changed files with 46 additions and 17 deletions.
32 changes: 16 additions & 16 deletions src/parsers/component-parser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export class ComponentParser {
if (!componentClass) return

const filters = this.parseFilters(getMember(componentClass, 'filters', {}))
const component = this.createComponentInstance(componentClass)
const component = ComponentParser.createComponentInstance(componentClass)
const computed = this.parseComputed(getMember(componentClass, 'computed', {}))
const template = getMember(componentClass, 'template', '')
const childComponentClasses = this.parseChildComponentClasses(componentClass, component)
Expand All @@ -30,6 +30,21 @@ export class ComponentParser {
})
}

public static createComponentInstance (componentClass: ComponentClass): CompiledComponent<{}> {
// TODO Do not `new Component` during SSR,
// see https://github.com/baidu/san-ssr/issues/42
const ComponentClass = componentClass
const proto = ComponentClass.prototype['__proto__'] // eslint-disable-line
const calcComputed = proto['_calcComputed']
const inited = ComponentClass.prototype['inited']
proto['_calcComputed'] = noop
ComponentClass.prototype['inited'] = undefined
const instance = new ComponentClass()
ComponentClass.prototype['inited'] = inited
proto['_calcComputed'] = calcComputed
return instance as CompiledComponent<{}>
}

private parseChildComponentClasses (componentClass: ComponentClass, component: CompiledComponent<{}>): Components {
const children: Components = new Map()

Expand All @@ -52,21 +67,6 @@ export class ComponentParser {
for (const child of aNode.children || []) this.visitANodeRecursively(child, visitor)
}

private createComponentInstance (componentClass: ComponentClass): CompiledComponent<{}> {
// TODO Do not `new Component` during SSR,
// see https://github.com/baidu/san-ssr/issues/42
const ComponentClass = componentClass
const proto = ComponentClass.prototype['__proto__'] // eslint-disable-line
const calcComputed = proto['_calcComputed']
const inited = ComponentClass.prototype['inited']
proto['_calcComputed'] = noop
ComponentClass.prototype['inited'] = undefined
const instance = new ComponentClass()
ComponentClass.prototype['inited'] = inited
proto['_calcComputed'] = calcComputed
return instance as CompiledComponent<{}>
}

private parseFilters (filters: any): Filters {
const ret: Filters = {}
for (const key of keys(filters)) {
Expand Down
3 changes: 2 additions & 1 deletion src/target-js/compilers/renderer-compiler.ts
Original file line number Diff line number Diff line change
Expand Up @@ -140,13 +140,14 @@ export class RendererCompiler {

this.genComponentContextCode(componentInfo)

// init data
// instance preraration
const defaultData = (component.initData && component.initData()) || {}
for (const key of Object.keys(defaultData)) {
emitter.writeLine('ctx.data["' + key + '"] = ctx.data["' + key + '"] || ' +
stringifier.any(defaultData[key]) + ';')
}
emitter.writeLine('ctx.instance.data = new SanData(ctx.data, ctx.instance.computed)')
emitter.writeLine(`ctx.instance.parentComponent = parentCtx && parentCtx.instance`)

// call inited
if (typeof component.inited === 'function') {
Expand Down
26 changes: 26 additions & 0 deletions test/cases/parent-component/component.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
const { Component } = require('san')

class Grid extends Component {
inited () {
const $parent = this.parentComponent
if ($parent.isRow) {
const padding = $parent.data.get('gutter')
this.data.set(
'cls',
`padding-${padding}`
)
}
}
}
Grid.template = '<span class="{{cls}}">{{content}}</span>'

class Row extends Component {
inited () {
this.isRow = true
this.data.set('gutter', 4)
}
}
Row.components = { 'grid': Grid }
Row.template = '<div><grid content="CONTENT"/></div>'

exports = module.exports = Row
1 change: 1 addition & 0 deletions test/cases/parent-component/data.json
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
{}
1 change: 1 addition & 0 deletions test/cases/parent-component/expected.html
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
<div><!--s-data:{"gutter":4}--><span class="padding-4">CONTENT</span></div>

0 comments on commit 480105c

Please sign in to comment.