Skip to content

Commit

Permalink
docs(website): add angular and vue guides
Browse files Browse the repository at this point in the history
  • Loading branch information
christianalfoni committed Jan 4, 2019
1 parent f7fdf4e commit 28ee895
Show file tree
Hide file tree
Showing 12 changed files with 325 additions and 5 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -57,19 +57,19 @@ export default connect({
target: 'markup',
code: `
<ul>
<li is="Post" v-for="post in overmind.state.postsList" v-bind:post="post" :key="post.id" />
<post-component v-for="post in overmind.state.postsList" v-bind:post="post" :key="post.id" />
</ul>
`,
},
{
fileName: 'components/Posts.vue (script)',
code: `
import { connect } from '../overmind'
import Post from './Post'
import PostComponent from './Post'
export default connect({
components: {
Post,
PostComponent,
},
})
`,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
export default () => [
{
fileName: 'overmind/index.ts',
code: `
import { Overmind, TConfig } from 'overmind'
import { createConnect, TConnect } from 'overmind-angular'
import { state } from './state'
import * as actions from './actions'
const config = {
state,
actions
}
declare module 'overmind' {
interface IConfig extends TConfig<typeof config> {}
}
export type Connect = TConnect<typeof config>
const overmind = new Overmind(config)
export const connect = createConnect(overmind)
`,
},
{
fileName: 'components/app.component.ts',
code: `
import { Component } from '@angular/core'
import { connect, Connect } from '../overmind'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css']
})
@connect()
export class AppComponent {
overmind: Connect
title = 'My First Angular App with Overmind!'
}
`,
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export default () => [
{
fileName: 'components/app.component.ts',
code: `
import { Component } from '@angular/core'
import { connect, Connect } from '../overmind'
@Component({
selector: 'app-root',
templateUrl: './app.component.html'
})
@connect()
export class AppComponent {
overmind: Connect
disposeMutationListener: () => void
ngOnInit() {
this.disposeMutationListener = this.overmind.addMutationListener((mutation) => {
if (mutation.path === 'currentPage') {
document.querySelector('#app').scrollTop = 0
}
})
}
ngOnDestroy() {
this.disposeMutationListener()
}
}
`,
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
export default () => [
{
fileName: 'components/app.component.ts',
code: `
import {
Component,
ChangeDetectionStrategy,
ChangeDetectorRef
} from '@angular/core'
import { connect, Connect } from '../overmind'
@Component({
selector: 'app-root',
templateUrl: './app.component.html',
styleUrls: ['./app.component.css'],
changeDetection: ChangeDetectionStrategy.OnPush
})
@connect()
export class AppComponent {
overmind: Connect
constructor(private cdr: ChangeDetectorRef) {}
}
`,
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
export default () => [
{
fileName: 'components/todo.component.ts',
code: `
import { Component, Input } from '@angular/core'
import { connect } from '../overmind'
import { Todo } from '../overmind/state'
@Component({
selector: 'todos-todo',
template: \`
<li>{{todo.title}}</li>
\`
})
@connect()
export class TodoComponent {
@Input() todo: Todo
}
`,
},
{
fileName: 'components/todos.component.ts',
code: `
import { Component } from '@angular/core'
import { connect } from '../overmind'
@Component({
selector: 'todos-list',
template: \`
<ul>
<todos-todo
*ngFor="let todo of overmind.state.todos"
[todo]="todo"
></todos-todo>
</ul>
\`
})
@connect()
export class ListComponent {}
`,
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
export default () => [
{
fileName: 'overmind/index.jsx',
code: `
import { Overmind } from 'overmind'
import { createConnect } from 'overmind-vue'
const overmind = new Overmind({
state: {},
actions: {}
})
export const connect = createConnect(overmind)
`,
},
{
fileName: 'components/SomeComponent.vue (template)',
code: `
<div v-on:click="overmind.actions.onClick">
{{overmind.state.foo}}
</div>
`,
},
{
fileName: 'components/SomeComponent.vue (script)',
code: `
import { connect } from '../overmind'
export default connect({})
`,
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export default () => [
{
fileName: 'components/SomeComponent.vue (template)',
code: `
<div v-on:click="overmind.actions.onClick">
{{overmind.state.foo}}
</div>
`,
},
{
fileName: 'components/SomeComponent.vue (script)',
code: `
import { connect } from '../overmind'
export default connect({
mounted() {
this.disposeMutationListener = this.overmind.addMutationListener((mutation) => {
if (mutation.path === 'currentPage') {
document.querySelector('#app').scrollTop = 0
}
})
},
destroyed() {
this.disposeMutationListener()
}
})
`,
},
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
export default () => [
{
fileName: 'overmind/index.jsx',
code: `
import { Overmind } from 'overmind'
import { createConnect } from 'overmind-vue'
const overmind = new Overmind({
state: {},
actions: {}
})
export const connect = createConnect(overmind)
`,
},
{
fileName: 'components/Todo.vue (template)',
code: `
<li>{{todo.title}}</li>
`,
},
{
fileName: 'components/Todo.vue (script)',
code: `
import { connect } from '../overmind'
export default connect({
props: ["todo"]
})
`,
},
{
fileName: 'components/Todos.vue (template)',
code: `
<ul>
<todo-component
v-for="post in overmind.state.postsList"
v-bind:todo="todo"
:key="todo.id"
/>
</ul>
`,
},
{
fileName: 'components/Todos.vue (script)',
code: `
import { connect } from '../overmind'
import TodoComponent from './Todo'
export default connect({
components: {
TodoComponent
}
})
`,
},
]
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ If you previously used **componentDidUpdate** to trigger an effect, that is no l

### Passing state as props

If you pass a state object or array as a property to a child component you will also in the child component need to **connect**. This ensures that the property you passed is tracked within that component, even though you do not access any state or actions. The devtools will help you identify where any components are left "unconnected".
If you pass a state object or array as a property to a child component you will also in the child component need to **connect**. This ensures that the property you passed is tracked within that component, even though you do not access any state or actions from Overmind. The devtools will help you identify where any components are left "unconnected".

```marksy
h(Example, { name: "guide/usingovermindwithreact/hoc_passprop" })
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
# Using Overmind with Angular

Using Overmind with Angular is straight forward. You create a **connect** decorator and use it with whatever component. An **overmind** property is added to the component and there you can access state, actions and listen to mutations to do effects.

```marksy
h(Example, { name: "guide/usingovermindwithangular/connect" })
```


## Rendering

When you connect Overmind to a component it will use its lifecycle hooks to manage updates. By default you really do not have to think about this as it relies on Angulars default change detection strategy.You can change this behaviour though. By adding the **onPush** strategy and injecting the **ChangeDetectorRef**, the component will only update when it receives input from its parents or Overmind tells it to update due to tracked state has changed.

```marksy
h(Example, { name: "guide/usingovermindwithangular/onpush" })
```

```marksy
h(Notice, null, "The class property has to be named **cdr**. Overmind gives an error if you use onPush strategy without injecting ChangeDetectorRef correctly.")
```

## Passing state as input

If you pass a state object or array as a property to a child component you will also in the child component need to **connect**. This ensures that the property you passed is tracked within that component, even though you do not access any state or actions from Overmind. The devtools will help you identify where any components are left "unconnected".

```marksy
h(Example, { name: "guide/usingovermindwithangular/passprop" })
```

## Effects

To run effects in components based on changes to state you use the **addMutationListener** function in the lifecycle hooks of Angular.

```marksy
h(Example, { name: "guide/usingovermindwithangular/effect" })
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
# Using Overmind with Vue

You can connect any Vue component to your Overmind instance.

```marksy
h(Example, { name: "guide/usingovermindwithvue/connect" })
```

## Rendering
Any state accessed in the component will cause the component to render when a mutation occurs on that state. Overmind actually uses the same approach to change detection as Vue itself.

## Pass state as props

If you pass a state object or array as a property to a child component you will also in the child component need to **connect**. This ensures that the property you passed is tracked within that component, even though you do not access any state or actions from Overmind. The devtools will help you identify where any components are left "unconnected".

```marksy
h(Example, { name: "guide/usingovermindwithvue/passprops" })
```

## Effects

To run effects in components based on changes to state you use the **addMutationListener** function in the lifecycle hooks of Vue.

```marksy
h(Example, { name: "guide/usingovermindwithvue/effect" })
```
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Routing
# State first routing

With Overmind you can use whatever routing solution your selected view layer provides. This will most likely intertwine routing state with your component state, which is something Overmind would discourage, but you know... whatever you feel productive in, you should use :-) In this guide we will look into how you can separate your router from your components and make it part of your application state instead. This is more in the spirit of Overmind and throughout this guide you will find benefits of doing it this way.

Expand Down

0 comments on commit 28ee895

Please sign in to comment.