data.js 3.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. var Watcher = require('../watcher')
  2. var Path = require('../parsers/path')
  3. var textParser = require('../parsers/text')
  4. var dirParser = require('../parsers/directive')
  5. var expParser = require('../parsers/expression')
  6. var filterRE = /[^|]\|[^|]/
  7. /**
  8. * Get the value from an expression on this vm.
  9. *
  10. * @param {String} exp
  11. * @return {*}
  12. */
  13. exports.$get = function (exp) {
  14. var res = expParser.parse(exp)
  15. if (res) {
  16. try {
  17. return res.get.call(this, this)
  18. } catch (e) {}
  19. }
  20. }
  21. /**
  22. * Set the value from an expression on this vm.
  23. * The expression must be a valid left-hand
  24. * expression in an assignment.
  25. *
  26. * @param {String} exp
  27. * @param {*} val
  28. */
  29. exports.$set = function (exp, val) {
  30. var res = expParser.parse(exp, true)
  31. if (res && res.set) {
  32. res.set.call(this, this, val)
  33. }
  34. }
  35. /**
  36. * Add a property on the VM
  37. *
  38. * @param {String} key
  39. * @param {*} val
  40. */
  41. exports.$add = function (key, val) {
  42. this._data.$add(key, val)
  43. }
  44. /**
  45. * Delete a property on the VM
  46. *
  47. * @param {String} key
  48. */
  49. exports.$delete = function (key) {
  50. this._data.$delete(key)
  51. }
  52. /**
  53. * Watch an expression, trigger callback when its
  54. * value changes.
  55. *
  56. * @param {String} exp
  57. * @param {Function} cb
  58. * @param {Object} [options]
  59. * - {Boolean} deep
  60. * - {Boolean} immediate
  61. * - {Boolean} user
  62. * @return {Function} - unwatchFn
  63. */
  64. exports.$watch = function (exp, cb, options) {
  65. var vm = this
  66. var wrappedCb = function (val, oldVal) {
  67. cb.call(vm, val, oldVal)
  68. }
  69. var watcher = new Watcher(vm, exp, wrappedCb, {
  70. deep: options && options.deep,
  71. user: !options || options.user !== false
  72. })
  73. if (options && options.immediate) {
  74. wrappedCb(watcher.value)
  75. }
  76. return function unwatchFn () {
  77. watcher.teardown()
  78. }
  79. }
  80. /**
  81. * Evaluate a text directive, including filters.
  82. *
  83. * @param {String} text
  84. * @return {String}
  85. */
  86. exports.$eval = function (text) {
  87. // check for filters.
  88. if (filterRE.test(text)) {
  89. var dir = dirParser.parse(text)[0]
  90. // the filter regex check might give false positive
  91. // for pipes inside strings, so it's possible that
  92. // we don't get any filters here
  93. var val = this.$get(dir.expression)
  94. return dir.filters
  95. ? this._applyFilters(val, null, dir.filters)
  96. : val
  97. } else {
  98. // no filter
  99. return this.$get(text)
  100. }
  101. }
  102. /**
  103. * Interpolate a piece of template text.
  104. *
  105. * @param {String} text
  106. * @return {String}
  107. */
  108. exports.$interpolate = function (text) {
  109. var tokens = textParser.parse(text)
  110. var vm = this
  111. if (tokens) {
  112. return tokens.length === 1
  113. ? vm.$eval(tokens[0].value)
  114. : tokens.map(function (token) {
  115. return token.tag
  116. ? vm.$eval(token.value)
  117. : token.value
  118. }).join('')
  119. } else {
  120. return text
  121. }
  122. }
  123. /**
  124. * Log instance data as a plain JS object
  125. * so that it is easier to inspect in console.
  126. * This method assumes console is available.
  127. *
  128. * @param {String} [path]
  129. */
  130. exports.$log = function (path) {
  131. var data = path
  132. ? Path.get(this._data, path)
  133. : this._data
  134. if (data) {
  135. data = JSON.parse(JSON.stringify(data))
  136. }
  137. console.log(data)
  138. }