jii
Version:
Jii - Full-Stack JavaScript Framework
140 lines (118 loc) • 3.87 kB
JavaScript
/**
* @author <a href="http://www.affka.ru">Vladimir Kozhin</a>
* @license MIT
*/
'use strict';
const Jii = require('../BaseJii');
const IRenderer = require('./IRenderer');
const InvalidConfigException = require('../exceptions/InvalidConfigException');
const ViewEvent = require('./ViewEvent');
const _isString = require('lodash/isString');
const _isFunction = require('lodash/isFunction');
const Component = require('../base/Component');
class View extends Component {
preInit() {
/**
* @type {object}
*/
this.renderers = null;
/**
* @type {IRenderer|null}
*/
this.renderer = null;
/**
* @type {mixed} custom parameters that are shared among view templates.
*/
this.params = null;
super.preInit(...arguments);
}
getRenderer(view) {
if (this.renderer instanceof IRenderer) {
return this.renderer;
}
// Auto detect
var name = View.RENDERER_UNDERSCORE;
if (_isString(this.renderer)) {
name = this.renderer;
} else if (_isString(view) && view.indexOf('/') !== -1) {
name = View.RENDERER_UNDERSCORE;
} else if (_isString(view) && view.indexOf('.') !== -1) {
view = Jii.namespace(view);
name = View.RENDERER_REACT;
} else if (_isFunction(view)) {
name = View.RENDERER_REACT;
}
if (name) {
if (!(this.renderers[name] instanceof IRenderer)) {
this.renderers[name] = Jii.createObject(this.renderers[name]);
}
return this.renderers[name];
}
throw new InvalidConfigException('Not found renderer for view');
}
/**
*
* @param {*} view
* @param {Context} context
* @param {object} params
* @param {Controller} controller
* @returns {Promise}
*/
render(view, context, params, controller) {
params = params || {};
context = context || null;
return this.beforeRender(view, context, params).then(success => {
if (!success) {
return false;
}
var output = this.getRenderer(view).render(view, context, params, controller, this);
return this.afterRender(view, context, params, output);
});
}
/**
*
* @param viewFile
* @param context
* @param params
* @returns {Promise.<boolean>}
*/
beforeRender(viewFile, context, params) {
var event = new ViewEvent({
viewFile: viewFile,
params: params
});
this.trigger(View.EVENT_BEFORE_RENDER, event);
return Promise.resolve(event.isValid);
}
/**
*
* @param viewFile
* @param context
* @param params
* @param output
* @returns {Promise.<*>}
*/
afterRender(viewFile, context, params, output) {
if (this.hasEventHandlers(View.EVENT_AFTER_RENDER)) {
var event = new ViewEvent({
viewFile: viewFile,
params: params,
output: output
});
this.trigger(View.EVENT_AFTER_RENDER, event);
output = event.output;
}
return Promise.resolve(output);
}
}
View.RENDERER_UNDERSCORE = 'underscore';
View.RENDERER_REACT = 'react';
/**
* @event ViewEvent an event that is triggered by [[renderFile()]] right after it renders a view file.
*/
View.EVENT_AFTER_RENDER = 'afterRender';
/**
* @event ViewEvent an event that is triggered by [[renderFile()]] right before it renders a view file.
*/
View.EVENT_BEFORE_RENDER = 'beforeRender';
module.exports = View;