Files
febbweiss.github.io/demo/filebrowser-durandal-widget/lib/durandal/js/binder.js
ECAILLE Fabrice (externe) e2277667c5 Fix: add dependencies
2017-05-04 10:26:11 +02:00

153 lines
5.6 KiB
JavaScript

/**
* Durandal 2.1.0 Copyright (c) 2012 Blue Spire Consulting, Inc. All Rights Reserved.
* Available via the MIT license.
* see: http://durandaljs.com or https://github.com/BlueSpire/Durandal for details.
*/
/**
* The binder joins an object instance and a DOM element tree by applying databinding and/or invoking binding lifecycle callbacks (binding and bindingComplete).
* @module binder
* @requires system
* @requires knockout
*/
define(['durandal/system', 'knockout'], function (system, ko) {
var binder,
insufficientInfoMessage = 'Insufficient Information to Bind',
unexpectedViewMessage = 'Unexpected View Type',
bindingInstructionKey = 'durandal-binding-instruction',
koBindingContextKey = '__ko_bindingContext__';
function normalizeBindingInstruction(result){
if(result === undefined){
return { applyBindings: true };
}
if(system.isBoolean(result)){
return { applyBindings:result };
}
if(result.applyBindings === undefined){
result.applyBindings = true;
}
return result;
}
function doBind(obj, view, bindingTarget, data){
if (!view || !bindingTarget) {
if (binder.throwOnErrors) {
system.error(insufficientInfoMessage);
} else {
system.log(insufficientInfoMessage, view, data);
}
return;
}
if (!view.getAttribute) {
if (binder.throwOnErrors) {
system.error(unexpectedViewMessage);
} else {
system.log(unexpectedViewMessage, view, data);
}
return;
}
var viewName = view.getAttribute('data-view');
try {
var instruction;
if (obj && obj.binding) {
instruction = obj.binding(view);
}
instruction = normalizeBindingInstruction(instruction);
binder.binding(data, view, instruction);
if(instruction.applyBindings){
system.log('Binding', viewName, data);
ko.applyBindings(bindingTarget, view);
}else if(obj){
ko.utils.domData.set(view, koBindingContextKey, { $data:obj });
}
binder.bindingComplete(data, view, instruction);
if (obj && obj.bindingComplete) {
obj.bindingComplete(view);
}
ko.utils.domData.set(view, bindingInstructionKey, instruction);
return instruction;
} catch (e) {
e.message = e.message + ';\nView: ' + viewName + ";\nModuleId: " + system.getModuleId(data);
if (binder.throwOnErrors) {
system.error(e);
} else {
system.log(e.message);
}
}
}
/**
* @class BinderModule
* @static
*/
return binder = {
/**
* Called before every binding operation. Does nothing by default.
* @method binding
* @param {object} data The data that is about to be bound.
* @param {DOMElement} view The view that is about to be bound.
* @param {object} instruction The object that carries the binding instructions.
*/
binding: system.noop,
/**
* Called after every binding operation. Does nothing by default.
* @method bindingComplete
* @param {object} data The data that has just been bound.
* @param {DOMElement} view The view that has just been bound.
* @param {object} instruction The object that carries the binding instructions.
*/
bindingComplete: system.noop,
/**
* Indicates whether or not the binding system should throw errors or not.
* @property {boolean} throwOnErrors
* @default false The binding system will not throw errors by default. Instead it will log them.
*/
throwOnErrors: false,
/**
* Gets the binding instruction that was associated with a view when it was bound.
* @method getBindingInstruction
* @param {DOMElement} view The view that was previously bound.
* @return {object} The object that carries the binding instructions.
*/
getBindingInstruction:function(view){
return ko.utils.domData.get(view, bindingInstructionKey);
},
/**
* Binds the view, preserving the existing binding context. Optionally, a new context can be created, parented to the previous context.
* @method bindContext
* @param {KnockoutBindingContext} bindingContext The current binding context.
* @param {DOMElement} view The view to bind.
* @param {object} [obj] The data to bind to, causing the creation of a child binding context if present.
* @param {string} [dataAlias] An alias for $data if present.
*/
bindContext: function(bindingContext, view, obj, dataAlias) {
if (obj && bindingContext) {
bindingContext = bindingContext.createChildContext(obj, typeof(dataAlias) === 'string' ? dataAlias : null);
}
return doBind(obj, view, bindingContext, obj || (bindingContext ? bindingContext.$data : null));
},
/**
* Binds the view, preserving the existing binding context. Optionally, a new context can be created, parented to the previous context.
* @method bind
* @param {object} obj The data to bind to.
* @param {DOMElement} view The view to bind.
*/
bind: function(obj, view) {
return doBind(obj, view, obj, obj);
}
};
});