Skip to content

Commit

Permalink
Un-depricate x-init, add returned callback behavior, and depricate x-…
Browse files Browse the repository at this point in the history
…created & x-mounted
  • Loading branch information
calebporzio committed Jan 10, 2020
1 parent 28ad366 commit 4d3a046
Show file tree
Hide file tree
Showing 6 changed files with 49 additions and 29 deletions.
26 changes: 4 additions & 22 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ Think of it like [Tailwind](https://tailwindcss.com/) for JavaScript.

**From CDN:** Add the following script to the end of your `<head>` section.
```html
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v1.6.2/dist/alpine.js" defer></script>
<script src="https://cdn.jsdelivr.net/gh/alpinejs/alpine@v1.7.0/dist/alpine.js" defer></script>
```

That's it. It will initialize itself.
Expand Down Expand Up @@ -84,14 +84,12 @@ You can even use it for non-trivial things:

## Learn

There are 14 directives available to you:
There are 12 directives available to you:

| Directive
| --- |
| [`x-data`](#x-data) |
| [`x-init`](#x-init) |
| [`x-created`](#x-created) |
| [`x-mounted`](#x-mounted) |
| [`x-show`](#x-show) |
| [`x-bind`](#x-bind) |
| [`x-on`](#x-on) |
Expand Down Expand Up @@ -158,32 +156,16 @@ You can also mix-in multiple data objects using object destructuring:

---

> Warning: `x-init` is depricated, in favor of using `x-created` or `x-mounted`. It will be removed in 2.0
### `x-init`
**Example:** `<div x-data"{ foo: 'bar' }" x-init="foo = 'baz"></div>`

**Structure:** `<div x-data="..." x-init="[expression]"></div>`

`x-init` runs an expression when a component is initialized.

---

### `x-created`
**Example:** `<div x-data="{ foo: 'bar' }" x-created="foo = 'baz"></div>`

**Structure:** `<div x-data="..." x-created="[expression]"></div>`

`x-created` runs an expression when a component is initialized, but BEFORE the component initializes the DOM.

---

### `x-mounted`
**Example:** `<div x-data="{ foo: 'bar' }" x-mounted="foo = 'baz"></div>`

**Structure:** `<div x-data="..." x-mounted="[expression]"></div>`
If you wish to run code AFTER Alpine has made it's initial updates to the DOM (something like a `mounted()` hook in VueJS), you can return a callback from `x-init`, and it will be run after:

`x-mounted` runs an expression when a component is initialized, and AFTER the component initializes the DOM.
`x-init="return () => { // we have access to the post-dom-initialization state here // }"`

---

Expand Down
2 changes: 1 addition & 1 deletion dist/alpine.js

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion dist/alpine.js.map

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"main": "dist/alpine.js",
"name": "alpinejs",
"version": "1.6.2",
"version": "1.7.0",
"repository": {
"type": "git",
"url": "git://github.com/alpinejs/alpine.git"
Expand Down
16 changes: 12 additions & 4 deletions src/component.js
Original file line number Diff line number Diff line change
Expand Up @@ -35,16 +35,17 @@ export default class Component {
this.tickStack = []
this.collectingTickCallbacks = false

var initReturnedCallback
if (initExpression) {
console.warn('AlpineJS Warning: "x-init" is depricated and will be removed in the next major version. Use "x-created" instead.')
// We want to allow data manipulation, but not trigger DOM updates just yet.
// We haven't even initialized the elements with their Alpine bindings. I mean c'mon.
this.pauseReactivity = true
saferEvalNoReturn(this.$el.getAttribute('x-init'), this.$data)
initReturnedCallback = saferEval(this.$el.getAttribute('x-init'), this.$data)
this.pauseReactivity = false
}

if (createdExpression) {
// We want to allow data manipulation, but not trigger DOM updates just yet.
// We haven't even initialized the elements with their Alpine bindings. I mean c'mon.
console.warn('AlpineJS Warning: "x-created" is depricated and will be removed in the next major version. Use "x-init" instead.')
this.pauseReactivity = true
saferEvalNoReturn(this.$el.getAttribute('x-created'), this.$data)
this.pauseReactivity = false
Expand All @@ -57,7 +58,14 @@ export default class Component {
// Alpine's just so darn flexible amirite?
this.listenForNewElementsToInitialize()

if (typeof initReturnedCallback === 'function') {
// Run the callback returned form the "x-init" hook to allow the user to do stuff after
// Alpine's got it's grubby little paws all over everything.
initReturnedCallback.call(this.$data)
}

if (mountedExpression) {
console.warn('AlpineJS Warning: "x-mounted" is depricated and will be removed in the next major version. Use "x-init" (with a callback return) for the same behavior.')
// Run an "x-mounted" hook to allow the user to do stuff after
// Alpine's got it's grubby little paws all over everything.
saferEvalNoReturn(mountedExpression, this.$data)
Expand Down
30 changes: 30 additions & 0 deletions test/lifecycle.spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,36 @@ test('x-init', async () => {
expect(spanValue).toEqual('baz')
})

test('x-init from data function with callback return for "x-mounted" functionality', async () => {
var valueA
var valueB
window.setValueA = (el) => { valueA = el.innerHTML }
window.setValueB = (el) => { valueB = el.innerText }
window.data = function() {
return {
foo: 'bar',
init() {
window.setValueA(this.$refs.foo)

return () => {
window.setValueB(this.$refs.foo)
}
}
}
}

document.body.innerHTML = `
<div x-data="window.data()" x-init="init()">
<span x-text="foo" x-ref="foo">baz</span>
</div>
`

Alpine.start()

expect(valueA).toEqual('baz')
expect(valueB).toEqual('bar')
})

test('x-created', async () => {
var spanValue
window.setSpanValue = (el) => {
Expand Down

0 comments on commit 4d3a046

Please sign in to comment.