parent
1bf6f98bde
commit
8bbff0ab16
@ -1,269 +0,0 @@ |
|||||||
'use strict'; |
|
||||||
/** |
|
||||||
* Bindonce - Zero watches binding for AngularJs |
|
||||||
* @version v0.2.2 - 2013-05-07 |
|
||||||
* @link https://github.com/Pasvaz/bindonce
|
|
||||||
* @author Pasquale Vazzana <pasqualevazzana@gmail.com> |
|
||||||
* @license MIT License, http://www.opensource.org/licenses/MIT
|
|
||||||
*/ |
|
||||||
|
|
||||||
angular.module('pasvaz.bindonce', []) |
|
||||||
|
|
||||||
.directive('bindonce', function()
|
|
||||||
{ |
|
||||||
var toBoolean = function(value)
|
|
||||||
{ |
|
||||||
if (value && value.length !== 0)
|
|
||||||
{ |
|
||||||
var v = angular.lowercase("" + value); |
|
||||||
value = !(v == 'f' || v == '0' || v == 'false' || v == 'no' || v == 'n' || v == '[]'); |
|
||||||
} |
|
||||||
else
|
|
||||||
{ |
|
||||||
value = false; |
|
||||||
} |
|
||||||
return value; |
|
||||||
} |
|
||||||
|
|
||||||
var msie = parseInt((/msie (\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10); |
|
||||||
if (isNaN(msie))
|
|
||||||
{ |
|
||||||
msie = parseInt((/trident\/.*; rv:(\d+)/.exec(angular.lowercase(navigator.userAgent)) || [])[1], 10); |
|
||||||
} |
|
||||||
|
|
||||||
var bindonceDirective = |
|
||||||
{ |
|
||||||
restrict: "AM", |
|
||||||
controller: ['$scope', '$element', '$attrs', '$interpolate', function($scope, $element, $attrs, $interpolate)
|
|
||||||
{ |
|
||||||
var showHideBinder = function(elm, attr, value)
|
|
||||||
{ |
|
||||||
var show = (attr == 'show') ? '' : 'none'; |
|
||||||
var hide = (attr == 'hide') ? '' : 'none'; |
|
||||||
elm.css('display', toBoolean(value) ? show : hide); |
|
||||||
} |
|
||||||
var classBinder = function(elm, value) |
|
||||||
{ |
|
||||||
if (angular.isObject(value) && !angular.isArray(value))
|
|
||||||
{ |
|
||||||
var results = []; |
|
||||||
angular.forEach(value, function(value, index)
|
|
||||||
{ |
|
||||||
if (value) results.push(index); |
|
||||||
}); |
|
||||||
value = results; |
|
||||||
} |
|
||||||
if (value)
|
|
||||||
{ |
|
||||||
elm.addClass(angular.isArray(value) ? value.join(' ') : value); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
var ctrl = |
|
||||||
{ |
|
||||||
watcherRemover : undefined, |
|
||||||
binders : [], |
|
||||||
group : $attrs.boName, |
|
||||||
element : $element, |
|
||||||
ran : false, |
|
||||||
|
|
||||||
addBinder : function(binder)
|
|
||||||
{ |
|
||||||
this.binders.push(binder); |
|
||||||
|
|
||||||
// In case of late binding (when using the directive bo-name/bo-parent)
|
|
||||||
// it happens only when you use nested bindonce, if the bo-children
|
|
||||||
// are not dom children the linking can follow another order
|
|
||||||
if (this.ran) |
|
||||||
{ |
|
||||||
this.runBinders(); |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
setupWatcher : function(bindonceValue)
|
|
||||||
{ |
|
||||||
var that = this; |
|
||||||
this.watcherRemover = $scope.$watch(bindonceValue, function(newValue)
|
|
||||||
{ |
|
||||||
if (newValue == undefined) return; |
|
||||||
that.removeWatcher(); |
|
||||||
that.runBinders(); |
|
||||||
}, true); |
|
||||||
}, |
|
||||||
|
|
||||||
removeWatcher : function()
|
|
||||||
{ |
|
||||||
if (this.watcherRemover != undefined) |
|
||||||
{ |
|
||||||
this.watcherRemover(); |
|
||||||
this.watcherRemover = undefined; |
|
||||||
} |
|
||||||
}, |
|
||||||
|
|
||||||
runBinders : function() |
|
||||||
{ |
|
||||||
var i, max; |
|
||||||
for (i = 0, max = this.binders.length; i < max; i ++) |
|
||||||
{ |
|
||||||
var binder = this.binders[i]; |
|
||||||
if (this.group && this.group != binder.group ) continue; |
|
||||||
var value = binder.scope.$eval((binder.interpolate) ? $interpolate(binder.value) : binder.value); |
|
||||||
switch(binder.attr) |
|
||||||
{ |
|
||||||
case 'if': |
|
||||||
if (toBoolean(value))
|
|
||||||
{ |
|
||||||
binder.transclude(binder.scope.$new(), function (clone)
|
|
||||||
{ |
|
||||||
var parent = binder.element.parent(); |
|
||||||
var afterNode = binder.element && binder.element[binder.element.length - 1]; |
|
||||||
var parentNode = parent && parent[0] || afterNode && afterNode.parentNode; |
|
||||||
var afterNextSibling = (afterNode && afterNode.nextSibling) || null; |
|
||||||
angular.forEach(clone, function(node)
|
|
||||||
{ |
|
||||||
parentNode.insertBefore(node, afterNextSibling); |
|
||||||
}); |
|
||||||
}); |
|
||||||
} |
|
||||||
break; |
|
||||||
case 'hide': |
|
||||||
case 'show': |
|
||||||
showHideBinder(binder.element, binder.attr, value); |
|
||||||
break; |
|
||||||
case 'class': |
|
||||||
classBinder(binder.element, value); |
|
||||||
break; |
|
||||||
case 'text': |
|
||||||
binder.element.text(value); |
|
||||||
break; |
|
||||||
case 'html': |
|
||||||
binder.element.html(value); |
|
||||||
break; |
|
||||||
case 'style': |
|
||||||
binder.element.css(value); |
|
||||||
break; |
|
||||||
case 'src': |
|
||||||
binder.element.attr(binder.attr, value); |
|
||||||
if (msie) binder.element.prop('src', value); |
|
||||||
case 'attr': |
|
||||||
angular.forEach(binder.attrs, function(attrValue, attrKey)
|
|
||||||
{ |
|
||||||
var newAttr, newValue; |
|
||||||
if (attrKey.match(/^boAttr./) && binder.attrs[attrKey])
|
|
||||||
{ |
|
||||||
newAttr = attrKey.replace(/^boAttr/, '').replace(/([a-z])([A-Z])/g, '$1-$2').toLowerCase(); |
|
||||||
newValue = binder.scope.$eval(binder.attrs[attrKey]); |
|
||||||
binder.element.attr(newAttr, newValue); |
|
||||||
} |
|
||||||
}); |
|
||||||
break; |
|
||||||
case 'href': |
|
||||||
case 'alt': |
|
||||||
case 'title': |
|
||||||
case 'id': |
|
||||||
case 'value': |
|
||||||
binder.element.attr(binder.attr, value); |
|
||||||
break; |
|
||||||
} |
|
||||||
} |
|
||||||
this.ran = true; |
|
||||||
this.binders = []; |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return ctrl; |
|
||||||
}], |
|
||||||
|
|
||||||
link: function(scope, elm, attrs, bindonceController)
|
|
||||||
{ |
|
||||||
var value = (attrs.bindonce) ? scope.$eval(attrs.bindonce) : true; |
|
||||||
if (value != undefined) |
|
||||||
{ |
|
||||||
bindonceController.runBinders(); |
|
||||||
} |
|
||||||
else |
|
||||||
{ |
|
||||||
bindonceController.setupWatcher(attrs.bindonce); |
|
||||||
elm.bind("$destroy", bindonceController.removeWatcher); |
|
||||||
} |
|
||||||
} |
|
||||||
}; |
|
||||||
|
|
||||||
return bindonceDirective; |
|
||||||
}); |
|
||||||
|
|
||||||
angular.forEach( |
|
||||||
[ |
|
||||||
{directiveName:'boShow', attribute: 'show'}, |
|
||||||
{directiveName:'boIf', attribute: 'if', transclude: 'element', terminal: true, priority:1000}, |
|
||||||
{directiveName:'boHide', attribute:'hide'}, |
|
||||||
{directiveName:'boClass', attribute:'class'}, |
|
||||||
{directiveName:'boText', attribute:'text'}, |
|
||||||
{directiveName:'boHtml', attribute:'html'}, |
|
||||||
{directiveName:'boSrcI', attribute:'src', interpolate:true}, |
|
||||||
{directiveName:'boSrc', attribute:'src'}, |
|
||||||
{directiveName:'boHrefI', attribute:'href', interpolate:true}, |
|
||||||
{directiveName:'boHref', attribute:'href'}, |
|
||||||
{directiveName:'boAlt', attribute:'alt'}, |
|
||||||
{directiveName:'boTitle', attribute:'title'}, |
|
||||||
{directiveName:'boId', attribute:'id'}, |
|
||||||
{directiveName:'boStyle', attribute:'style'}, |
|
||||||
{directiveName:'boValue', attribute:'value'}, |
|
||||||
{directiveName:'boAttr', attribute:'attr'} |
|
||||||
], |
|
||||||
function(boDirective) |
|
||||||
{ |
|
||||||
var childPriority = 200; |
|
||||||
return angular.module('pasvaz.bindonce').directive(boDirective.directiveName, function()
|
|
||||||
{ |
|
||||||
var bindonceDirective = |
|
||||||
{
|
|
||||||
priority: boDirective.priority || childPriority, |
|
||||||
transclude: boDirective.transclude || false,
|
|
||||||
terminal: boDirective.terminal || false,
|
|
||||||
require: '^bindonce',
|
|
||||||
compile: function (tElement, tAttrs, transclude)
|
|
||||||
{ |
|
||||||
return function(scope, elm, attrs, bindonceController) |
|
||||||
{ |
|
||||||
var name = attrs.boParent; |
|
||||||
if (name && bindonceController.group != name) |
|
||||||
{ |
|
||||||
var element = bindonceController.element.parent(); |
|
||||||
bindonceController = undefined; |
|
||||||
var parentValue; |
|
||||||
|
|
||||||
while (element[0].nodeType != 9 && element.length) |
|
||||||
{ |
|
||||||
if ((parentValue = element.data('$bindonceController'))
|
|
||||||
&& parentValue.group == name) |
|
||||||
{ |
|
||||||
bindonceController = parentValue |
|
||||||
break; |
|
||||||
} |
|
||||||
element = element.parent(); |
|
||||||
} |
|
||||||
if (!bindonceController) |
|
||||||
{ |
|
||||||
throw Error("No bindonce controller: " + name); |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
bindonceController.addBinder( |
|
||||||
{ |
|
||||||
element : elm, |
|
||||||
attr : boDirective.attribute, |
|
||||||
attrs : attrs, |
|
||||||
value : attrs[boDirective.directiveName], |
|
||||||
interpolate : boDirective.interpolate, |
|
||||||
group : name, |
|
||||||
transclude : transclude, |
|
||||||
scope : scope |
|
||||||
}); |
|
||||||
} |
|
||||||
} |
|
||||||
} |
|
||||||
|
|
||||||
return bindonceDirective; |
|
||||||
}); |
|
||||||
}); |
|
File diff suppressed because one or more lines are too long
Loading…
Reference in new issue