Skip to content

Commit

Permalink
v-el
Browse files Browse the repository at this point in the history
  • Loading branch information
yyx990803 committed Sep 11, 2014
1 parent 813846a commit d36ea57
Show file tree
Hide file tree
Showing 8 changed files with 68 additions and 49 deletions.
1 change: 1 addition & 0 deletions component.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"src/directives/class.js",
"src/directives/cloak.js",
"src/directives/component.js",
"src/directives/el.js",
"src/directives/html.js",
"src/directives/if.js",
"src/directives/index.js",
Expand Down
11 changes: 2 additions & 9 deletions src/compile/compile.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ function noop () {}
* @return {Function}
*/

var compile = module.exports = function (el, options) {
module.exports = function compile (el, options) {
// for template tags, what we want is its content as
// a documentFragment (for block instances)
if (el.tagName === 'TEMPLATE') {
Expand Down Expand Up @@ -382,15 +382,8 @@ function checkTerminalDirectives (el, options) {
function makeTeriminalLinkFn (el, dirName, value, options) {
var descriptor = dirParser.parse(value)[0]
var def = options.directives[dirName]
if (
dirName === 'repeat' &&
!el.hasAttribute(config.prefix + 'component')
) {
// optimize for simple repeats
var linker = compile(el, options)
}
return function terminalLinkFn (vm, el) {
vm._bindDir(dirName, el, descriptor, def, linker)
vm._bindDir(dirName, el, descriptor, def)
}
}

Expand Down
14 changes: 14 additions & 0 deletions src/directives/el.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
module.exports = {

isLiteral: true,

bind: function () {
this.owner = this.vm._owner || this.vm
this.owner.$$[this.expression] = this.el
},

unbind: function () {
this.owner.$$[this.expression] = null
}

}
1 change: 1 addition & 0 deletions src/directives/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ exports.html = require('./html')
exports.attr = require('./attr')
exports.show = require('./show')
exports['class'] = require('./class')
exports.el = require('./el')
exports.ref = require('./ref')
exports.cloak = require('./cloak')
exports.style = require('./style')
Expand Down
18 changes: 3 additions & 15 deletions src/directives/ref.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,24 +11,12 @@ module.exports = {
)
return
}
var id = this.expression
if (id) {
var owner = this.vm.$parent
// find the first parent vm that is not an
// anonymous instance.
while (owner._isAnonymous) {
owner = owner.$parent
}
owner.$[id] = this.vm
this.owner = owner
}
this.owner = this.vm._owner || this.vm
this.owner.$[this.expression] = this.vm
},

unbind: function () {
var id = this.expression
if (id) {
delete this.owner.$[id]
}
this.owner.$[this.expression] = null
}

}
50 changes: 28 additions & 22 deletions src/directives/repeat.js
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,8 @@ module.exports = {
// at v-repeat level
this.checkIf()
this.checkRef()
this.checkComponent()
this.checkTrackById()
this.checkComponent()
// setup ref node
this.ref = document.createComment('v-repeat')
// cache for primitive value instances
Expand All @@ -55,21 +55,34 @@ module.exports = {
},

/**
* Check if v-ref is also present. If yes, evaluate it and
* locate the first non-anonymous parent as the owner vm.
* Check if v-ref/ v-el is also present. If yes, evaluate
* them and locate owner.
*/

checkRef: function () {
var childId = _.attr(this.el, 'ref')
this.childId = childId
? this.vm.$interpolate(childId)
: null
if (this.childId) {
var owner = this.vm.$parent
while (owner._isAnonymous) {
owner = owner.$parent
}
this.owner = owner
var elId = _.attr(this.el, 'el')
this.elId = elId
? this.vm.$interpolate(elId)
: null
if (this.childId || this.elId) {
this.owner = this.vm._owner || this.vm
}
},

/**
* Check for a track-by ID, which allows us to identify
* a piece of data and its associated instance by its
* unique id.
*/

checkTrackById: function () {
this.idKey = this.el.getAttribute('trackby')
if (this.idKey !== null) {
this.el.removeAttribute('trackby')
}
},

Expand All @@ -84,6 +97,7 @@ module.exports = {
if (!id) {
this.Ctor = _.Vue // default constructor
this.inherit = true // inline repeats should inherit
this._linker = compile(this.el, _.Vue.options)
} else {
var tokens = textParser.parse(id)
if (!tokens) { // static component
Expand All @@ -107,19 +121,6 @@ module.exports = {
}
},

/**
* Check for a track-by ID, which allows us to identify
* a piece of data and its associated instance by its
* unique id.
*/

checkTrackById: function () {
this.idKey = this.el.getAttribute('trackby')
if (this.idKey !== null) {
this.el.removeAttribute('trackby')
}
},

/**
* Update.
* This is called whenever the Array mutates.
Expand All @@ -141,6 +142,11 @@ module.exports = {
if (this.childId) {
this.owner.$[this.childId] = this.vms
}
if (this.elId) {
this.owner.$$[this.elId] = this.vms.map(function (vm) {
return vm.$el
})
}
},

/**
Expand Down
11 changes: 10 additions & 1 deletion src/instance/init.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,16 @@ exports._init = function (options) {
// child constructors

// anonymous instances are created by v-if
this._isAnonymous = options._anonymous
// we need to walk along the parent chain to locate the
// first non-anonymous instance as the owner.
var anon = this._isAnonymous = options._anonymous
if (anon) {
var parent = this.$parent
while (parent._isAnonymous) {
parent = parent.$parent
}
this._owner = parent
}

// merge options.
options = this.$options = mergeOptions(
Expand Down
11 changes: 9 additions & 2 deletions test/unit/specs/instance/init_spec.js
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,14 @@ describe('Instance Init', function () {
$mount: jasmine.createSpy()
}

init.call(stub, {
var options = {
a: 2,
_anonymous: true,
_parent: {},
el: {}
})
}

init.call(stub, options)

it('should setup properties', function () {
expect(stub.$el).toBe(null)
Expand All @@ -36,6 +39,10 @@ describe('Instance Init', function () {
expect(stub.$options.b).toBe(2)
})

it('should locate owner', function () {
expect(stub._owner).toBe(options._parent)
})

it('should call other init methods', function () {
expect(stub._initEvents).toHaveBeenCalled()
expect(stub._initScope).toHaveBeenCalled()
Expand Down

0 comments on commit d36ea57

Please sign in to comment.