| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128 |
- var Compiler = require('./compiler')
- /*
- * ViewModel exposed to the user that holds data,
- * computed properties, event handlers
- * and a few reserved methods
- */
- function ViewModel (options) {
- // just compile. options are passed directly to compiler
- new Compiler(this, options)
- }
- var VMProto = ViewModel.prototype
- /*
- * Convenience function to set an actual nested value
- * from a flat key string. Used in directives.
- */
- VMProto.$set = function (key, value) {
- var path = key.split('.'),
- obj = getTargetVM(this, path)
- if (!obj) return
- for (var d = 0, l = path.length - 1; d < l; d++) {
- obj = obj[path[d]]
- }
- obj[path[d]] = value
- }
- /*
- * The function for getting a key
- * which will go up along the prototype chain of the bindings
- * Used in exp-parser.
- */
- VMProto.$get = function (key) {
- var path = key.split('.'),
- obj = getTargetVM(this, path),
- vm = obj
- if (!obj) return
- for (var d = 0, l = path.length; d < l; d++) {
- obj = obj[path[d]]
- }
- if (typeof obj === 'function') obj = obj.bind(vm)
- return obj
- }
- /*
- * watch a key on the viewmodel for changes
- * fire callback with new value
- */
- VMProto.$watch = function (key, callback) {
- this.$compiler.observer.on('change:' + key, callback)
- }
- /*
- * unwatch a key
- */
- VMProto.$unwatch = function (key, callback) {
- // workaround here
- // since the emitter module checks callback existence
- // by checking the length of arguments
- var args = ['change:' + key],
- ob = this.$compiler.observer
- if (callback) args.push(callback)
- ob.off.apply(ob, args)
- }
- /*
- * unbind everything, remove everything
- */
- VMProto.$destroy = function () {
- this.$compiler.destroy()
- this.$compiler = null
- }
- /*
- * broadcast an event to all child VMs recursively.
- */
- VMProto.$broadcast = function () {
- var children = this.$compiler.childCompilers,
- i = children.length,
- child
- while (i--) {
- child = children[i]
- child.emitter.emit.apply(child.emitter, arguments)
- child.vm.$broadcast.apply(child.vm, arguments)
- }
- }
- /*
- * emit an event that propagates all the way up to parent VMs.
- */
- VMProto.$emit = function () {
- var parent = this.$compiler.parentCompiler
- if (parent) {
- parent.emitter.emit.apply(parent.emitter, arguments)
- parent.vm.$emit.apply(parent.vm, arguments)
- }
- }
- /*
- * listen for a broadcasted/emitted event
- */
- VMProto.$on = function () {
- var emitter = this.$compiler.emitter
- emitter.on.apply(emitter, arguments)
- }
- /*
- * stop listening
- */
- VMProto.$off = function () {
- var emitter = this.$compiler.emitter
- emitter.off.apply(emitter, arguments)
- }
- /*
- * If a VM doesn't contain a path, go up the prototype chain
- * to locate the ancestor that has it.
- */
- function getTargetVM (vm, path) {
- var baseKey = path[0],
- binding = vm.$compiler.bindings[baseKey]
- return binding
- ? binding.compiler.vm
- : null
- }
- module.exports = ViewModel
|