2014-08-11 01:32:54 +08:00
|
|
|
var Watcher = require('../watcher')
|
2014-11-25 06:23:42 +08:00
|
|
|
var Path = require('../parsers/path')
|
|
|
|
|
var textParser = require('../parsers/text')
|
|
|
|
|
var dirParser = require('../parsers/directive')
|
|
|
|
|
var expParser = require('../parsers/expression')
|
2014-08-11 10:17:30 +08:00
|
|
|
var filterRE = /[^|]\|[^|]/
|
2014-08-11 01:32:54 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Get the value from an expression on this vm.
|
|
|
|
|
*
|
|
|
|
|
* @param {String} exp
|
2015-09-15 23:09:19 +08:00
|
|
|
* @param {Boolean} [asStatement]
|
2014-08-11 01:32:54 +08:00
|
|
|
* @return {*}
|
|
|
|
|
*/
|
|
|
|
|
|
2015-09-15 23:09:19 +08:00
|
|
|
exports.$get = function (exp, asStatement) {
|
2014-08-11 01:32:54 +08:00
|
|
|
var res = expParser.parse(exp)
|
|
|
|
|
if (res) {
|
2015-09-15 23:09:19 +08:00
|
|
|
if (asStatement && !expParser.isSimplePath(exp)) {
|
|
|
|
|
var self = this
|
|
|
|
|
return function statementHandler () {
|
|
|
|
|
res.get.call(self, self)
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
try {
|
|
|
|
|
return res.get.call(this, this)
|
|
|
|
|
} catch (e) {}
|
|
|
|
|
}
|
2014-08-11 01:32:54 +08:00
|
|
|
}
|
2014-07-09 03:57:47 +08:00
|
|
|
}
|
|
|
|
|
|
2014-08-11 01:32:54 +08:00
|
|
|
/**
|
|
|
|
|
* Set the value from an expression on this vm.
|
2014-08-11 02:12:22 +08:00
|
|
|
* The expression must be a valid left-hand
|
|
|
|
|
* expression in an assignment.
|
2014-08-11 01:32:54 +08:00
|
|
|
*
|
|
|
|
|
* @param {String} exp
|
|
|
|
|
* @param {*} val
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
exports.$set = function (exp, val) {
|
|
|
|
|
var res = expParser.parse(exp, true)
|
|
|
|
|
if (res && res.set) {
|
2014-08-25 11:47:36 +08:00
|
|
|
res.set.call(this, this, val)
|
2014-08-11 01:32:54 +08:00
|
|
|
}
|
2014-07-09 03:57:47 +08:00
|
|
|
}
|
|
|
|
|
|
2014-08-11 01:32:54 +08:00
|
|
|
/**
|
2014-08-11 02:12:22 +08:00
|
|
|
* Delete a property on the VM
|
2014-08-11 01:32:54 +08:00
|
|
|
*
|
|
|
|
|
* @param {String} key
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
exports.$delete = function (key) {
|
2014-09-17 08:50:17 +08:00
|
|
|
this._data.$delete(key)
|
2014-07-14 22:43:48 +08:00
|
|
|
}
|
|
|
|
|
|
2014-08-11 01:32:54 +08:00
|
|
|
/**
|
2014-08-11 02:12:22 +08:00
|
|
|
* Watch an expression, trigger callback when its
|
2014-08-29 07:02:32 +08:00
|
|
|
* value changes.
|
2014-08-11 01:32:54 +08:00
|
|
|
*
|
|
|
|
|
* @param {String} exp
|
|
|
|
|
* @param {Function} cb
|
2015-06-11 16:25:41 +08:00
|
|
|
* @param {Object} [options]
|
|
|
|
|
* - {Boolean} deep
|
|
|
|
|
* - {Boolean} immediate
|
|
|
|
|
* - {Boolean} user
|
2014-08-29 09:55:32 +08:00
|
|
|
* @return {Function} - unwatchFn
|
2014-08-11 01:32:54 +08:00
|
|
|
*/
|
|
|
|
|
|
2015-06-11 16:25:41 +08:00
|
|
|
exports.$watch = function (exp, cb, options) {
|
2014-08-29 09:55:32 +08:00
|
|
|
var vm = this
|
2015-08-17 06:06:24 +08:00
|
|
|
var watcher = new Watcher(vm, exp, cb, {
|
2015-06-11 16:25:41 +08:00
|
|
|
deep: options && options.deep,
|
|
|
|
|
user: !options || options.user !== false
|
2015-05-27 08:55:27 +08:00
|
|
|
})
|
2015-06-11 16:25:41 +08:00
|
|
|
if (options && options.immediate) {
|
2015-08-17 06:06:24 +08:00
|
|
|
cb.call(vm, watcher.value)
|
2014-08-18 02:13:52 +08:00
|
|
|
}
|
2014-08-29 09:55:32 +08:00
|
|
|
return function unwatchFn () {
|
2015-05-27 08:55:27 +08:00
|
|
|
watcher.teardown()
|
2014-08-11 01:32:54 +08:00
|
|
|
}
|
2014-07-14 22:43:48 +08:00
|
|
|
}
|
|
|
|
|
|
2014-08-11 10:17:30 +08:00
|
|
|
/**
|
|
|
|
|
* Evaluate a text directive, including filters.
|
|
|
|
|
*
|
|
|
|
|
* @param {String} text
|
2015-09-15 23:09:19 +08:00
|
|
|
* @param {Boolean} [asStatement]
|
2014-08-11 10:17:30 +08:00
|
|
|
* @return {String}
|
|
|
|
|
*/
|
|
|
|
|
|
2015-09-15 23:09:19 +08:00
|
|
|
exports.$eval = function (text, asStatement) {
|
2014-08-11 10:17:30 +08:00
|
|
|
// check for filters.
|
|
|
|
|
if (filterRE.test(text)) {
|
2015-09-03 04:43:18 +08:00
|
|
|
var dir = dirParser.parse(text)
|
2014-08-11 10:17:30 +08:00
|
|
|
// the filter regex check might give false positive
|
|
|
|
|
// for pipes inside strings, so it's possible that
|
|
|
|
|
// we don't get any filters here
|
2015-09-15 23:09:19 +08:00
|
|
|
var val = this.$get(dir.expression, asStatement)
|
2014-08-11 10:17:30 +08:00
|
|
|
return dir.filters
|
2015-05-29 03:13:35 +08:00
|
|
|
? this._applyFilters(val, null, dir.filters)
|
|
|
|
|
: val
|
2014-08-11 10:17:30 +08:00
|
|
|
} else {
|
|
|
|
|
// no filter
|
2015-09-15 23:09:19 +08:00
|
|
|
return this.$get(text, asStatement)
|
2014-08-11 10:17:30 +08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
2014-08-11 01:32:54 +08:00
|
|
|
/**
|
2014-08-11 04:46:20 +08:00
|
|
|
* Interpolate a piece of template text.
|
2014-08-11 01:32:54 +08:00
|
|
|
*
|
2014-08-11 04:46:20 +08:00
|
|
|
* @param {String} text
|
2014-08-11 02:12:22 +08:00
|
|
|
* @return {String}
|
2014-08-11 01:32:54 +08:00
|
|
|
*/
|
|
|
|
|
|
2014-08-11 04:46:20 +08:00
|
|
|
exports.$interpolate = function (text) {
|
2014-08-11 10:17:30 +08:00
|
|
|
var tokens = textParser.parse(text)
|
|
|
|
|
var vm = this
|
|
|
|
|
if (tokens) {
|
2015-09-24 03:32:27 +08:00
|
|
|
if (tokens.length === 1) {
|
2015-09-24 03:38:38 +08:00
|
|
|
return vm.$eval(tokens[0].value) + ''
|
2015-09-24 03:32:27 +08:00
|
|
|
} else {
|
|
|
|
|
return tokens.map(function (token) {
|
|
|
|
|
return token.tag
|
|
|
|
|
? vm.$eval(token.value)
|
|
|
|
|
: token.value
|
|
|
|
|
}).join('')
|
|
|
|
|
}
|
2014-08-11 10:17:30 +08:00
|
|
|
} else {
|
|
|
|
|
return text
|
|
|
|
|
}
|
2014-07-14 22:43:48 +08:00
|
|
|
}
|
|
|
|
|
|
2014-08-11 01:32:54 +08:00
|
|
|
/**
|
|
|
|
|
* Log instance data as a plain JS object
|
|
|
|
|
* so that it is easier to inspect in console.
|
|
|
|
|
* This method assumes console is available.
|
|
|
|
|
*
|
2014-11-06 12:29:50 +08:00
|
|
|
* @param {String} [path]
|
2014-08-11 01:32:54 +08:00
|
|
|
*/
|
|
|
|
|
|
2014-11-06 12:29:50 +08:00
|
|
|
exports.$log = function (path) {
|
|
|
|
|
var data = path
|
2014-12-01 03:22:46 +08:00
|
|
|
? Path.get(this._data, path)
|
2014-11-06 12:29:50 +08:00
|
|
|
: this._data
|
2014-12-01 03:22:46 +08:00
|
|
|
if (data) {
|
2015-09-06 04:52:08 +08:00
|
|
|
data = clean(data)
|
2014-12-01 03:22:46 +08:00
|
|
|
}
|
2015-09-06 04:35:21 +08:00
|
|
|
// include computed fields
|
|
|
|
|
if (!path) {
|
|
|
|
|
for (var key in this.$options.computed) {
|
2015-09-06 04:52:08 +08:00
|
|
|
data[key] = clean(this[key])
|
2015-09-06 04:35:21 +08:00
|
|
|
}
|
|
|
|
|
}
|
2014-12-01 03:22:46 +08:00
|
|
|
console.log(data)
|
2015-06-11 16:25:41 +08:00
|
|
|
}
|
2015-09-06 04:52:08 +08:00
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* "clean" a getter/setter converted object into a plain
|
|
|
|
|
* object copy.
|
|
|
|
|
*
|
|
|
|
|
* @param {Object} - obj
|
|
|
|
|
* @return {Object}
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
function clean (obj) {
|
|
|
|
|
return JSON.parse(JSON.stringify(obj))
|
|
|
|
|
}
|