Beispiel #1
0
function flushChanges () {
	var i, thing, changeHash;

	while ( batch.ractives.length ) {
		thing = batch.ractives.pop();
		changeHash = thing.viewmodel.applyChanges();

		if ( changeHash ) {
			changeHook.fire( thing, changeHash );
		}
	}

	attemptKeypathResolution();

	// Now that changes have been fully propagated, we can update the DOM
	// and complete other tasks
	for ( i = 0; i < batch.views.length; i += 1 ) {
		batch.views[i].update();
	}
	batch.views.length = 0;

	for ( i = 0; i < batch.tasks.length; i += 1 ) {
		batch.tasks[i]();
	}
	batch.tasks.length = 0;

	// If updating the view caused some model blowback - e.g. a triple
	// containing <option> elements caused the binding on the <select>
	// to update - then we start over
	if ( batch.ractives.length ) return flushChanges();
}
Beispiel #2
0
export default function Component$unbind () {
	var instance = this.instance;

	this.resolvers.forEach( unbind );

	removeFromLiveComponentQueries( this );

	instance._observers.forEach( cancel );

	// teardown the instance
	instance.fragment.unbind();
	instance.viewmodel.teardown();

	if ( instance.fragment.rendered && instance.el.__ractive_instances__ ) {
		removeFromArray( instance.el.__ractive_instances__, instance );
	}

	teardownHook.fire( instance );
}
Beispiel #3
0
export default function Ractive$update ( keypath, callback ) {
	var promise;

	if ( typeof keypath === 'function' ) {
		callback = keypath;
		keypath = '';
	} else {
		keypath = keypath || '';
	}

	promise = runloop.start( this, true );

	this.viewmodel.mark( keypath );
	runloop.end();

	updateHook.fire( this, keypath );

	if ( callback ) {
		promise.then( callback.bind( this ) );
	}

	return promise;
}
Beispiel #4
0
export default function Component$detach () {
	var detached = this.instance.fragment.detach();
	detachHook.fire( this.instance );
	return detached;
}
Beispiel #5
0
export default function initialiseRactiveInstance ( ractive, options = {} ) {

	var el;

	initialiseProperties( ractive, options );

	// make this option do what would be expected if someone
	// did include it on a new Ractive() or new Component() call.
	// Silly to do so (put a hook on the very options being used),
	// but handle it correctly, consistent with the intent.
	constructHook.fire( config.getConstructTarget( ractive, options ), options );

	// init config from Parent and options
	config.init( ractive.constructor, ractive, options );

	configHook.fire( ractive );

	// Teardown any existing instances *before* trying to set up the new one -
	// avoids certain weird bugs
	if ( el = getElement( ractive.el ) ) {
		if ( !ractive.append ) {
			if ( el.__ractive_instances__ ) {
				try {
					el.__ractive_instances__.splice( 0, el.__ractive_instances__.length ).forEach( r => r.teardown() );
				} catch ( err ) {
					// this can happen with IE8, because it is unbelievably shit. Somehow, in
					// certain very specific situations, trying to access node.parentNode (which
					// we need to do in order to detach elements) causes an 'Invalid argument'
					// error to be thrown. I don't even.
				}
			}

			el.innerHTML = ''; // TODO is this quicker than removeChild? Initial research inconclusive
		}
	}

	initHook.begin( ractive );

	// TEMPORARY. This is so we can implement Viewmodel gradually
	ractive.viewmodel = new Viewmodel( ractive );

	// hacky circular problem until we get this sorted out
	// if viewmodel immediately processes computed properties,
	// they may call ractive.get, which calls ractive.viewmodel,
	// which hasn't been set till line above finishes.
	ractive.viewmodel.init();

	// Render our *root fragment*
	if ( ractive.template ) {
		ractive.fragment = new Fragment({
			template: ractive.template,
			root: ractive,
			owner: ractive, // saves doing `if ( this.parent ) { /*...*/ }` later on
		});
	}

	initHook.end( ractive );

	// render automatically ( if `el` is specified )
	if ( el ) {
		ractive.render( el, ractive.append );
	}
}