modules.define('bemdom', ['i-bem__dom'], function(provide, BEMDOM) {
provide(BEMDOM);
});
modules.define('angular-bem',
['BEMHTML', 'bemdom', 'jquery', 'i-bem__dom_init'],
function(provide, BEMHTML, BEMDOM, $) {
angular.module('angular-bem', [])
.value('bemhtml', BEMHTML)
.value('bemdom', BEMDOM)
.factory('ngbem', ngBemFactory)
.directive('ngBem', ngBemDirective)
.directive('bem', iBemDirective)
.directive('bemMod', bemModDirective)
.directive('bemEvent', bemEventDirective)
.directive('menuItem', menuItemDirective);
function ngBemFactory($compile) {
var service = { render : render };
return service;
function render(bemjson, element, scope) {
element.replaceWith(
$compile(BEMHTML.apply(bemjson))(scope)
);
}
}
function ngBemDirective(ngbem) {
return {
restrict : 'E',
link : function(scope, element, attrs) {
var bemjson = scope.$eval(attrs.bemJson || element.text());
ngbem.render(bemjson, element, scope);
}
};
}
function bemController($scope, $attrs, $element) {
this.bem = $scope.$eval($attrs.bem);
angular.forEach(this.bem, function(v, k) {
this.bem[k] = function(){
return $($element).bem(k);
};
}, this);
}
function iBemDirective() {
return {
restrict : 'A',
require : ['bem', '?ngModel'],
controller : bemController,
link : function(scope, element, attrs, ctrls) {
scope.$evalAsync(function(){
var iBem = ctrls[0],
ngModel = ctrls[1];
if(!ngModel) return;
angular.forEach(iBem.bem, function(v, k) {
// iBem.bem[k] = $(element).bem(k);
iBem.bem[k]().on('change', function(e, data) {
if(data && data.source === 'ng-model') {
scope.$evalAsync(setModelValue.bind(iBem.bem[k]()));
} else {
scope.$evalAsync(setViewValue.bind(iBem.bem[k]()));
}
});
setModelValue.bind(iBem.bem[k]())();
});
ngModel.$render = function() {
var value = angular.isUndefined(ngModel.$viewValue)? '' : ngModel.$viewValue;
angular.forEach(iBem.bem, function(v, k) {
if(iBem.bem[k]().setVal) iBem.bem[k]().setVal(value, { source : 'ng-model' });
});
};
function setViewValue() {
ngModel.$setViewValue(this.getVal());
}
function setModelValue() {
// prevents calling of ng-change listeners
ngModel.$modelValue = this.getVal();
}
})
}
};
}
function bemModDirective() {
return {
restrict : 'A',
require : 'bem',
link : function(scope, element, attrs, iBem) {
var oldVal;
scope.$watch(attrs.bemMod, bemModWatchAction, true);
function setMods(newVal) {
angular.forEach(newVal, function(v, block) {
angular.forEach(v, function(modVal, modName) {
this.setMod(modName, modVal);
}, iBem.bem[block]);
});
}
function bemModWatchAction(newVal) {
if(!angular.equals(newVal, oldVal)) {
setMods(newVal);
}
oldVal = shallowCopy(newVal);
}
}
};
}
function bemEventDirective($parse) {
return {
restrict : 'A',
require : 'bem',
link : function(scope, element, attrs, iBem) {
var events = scope.$eval(attrs.bemEvent);
angular.forEach(events, function(eventsArray, block) {
angular.forEach(eventsArray, function(eventDefenition) {
var event,
fn;
if(eventDefenition.length === 2) {
event = eventDefenition[0];
fn = $parse(eventDefenition[1], null, true);
} else if(eventDefenition.length === 3) {
event = {
modName : eventDefenition[0],
modVal : eventDefenition[1]
};
fn = $parse(eventDefenition[2], null, true);
}
this.on(event, function() {
scope.$apply(function() {
fn(scope);
});
});
}, iBem.bem[block]);
});
}
};
}
function menuItemDirective() {
return {
restrict: 'C',
require : 'bem',
link : function(scope, element, attrs, iBem) {
scope.$evalAsync(function(){
var menu = iBem.bem['menu-item']().findBlockOutside('menu');
menu._hoveredItem = null;
menu._items = null;
menu.getItems().delMod('checked');
menu.setVal(menu.getVal() || menu.getItems()[0].getVal());
});
}
};
}
function shallowCopy(src, dst) {
if(angular.isArray(src)) {
dst = dst || [];
for(var i = 0, ii = src.length; i < ii; i++) {
dst[i] = src[i];
}
} else if(angular.isObject(src)) {
dst = dst || {};
for(var key in src) {
if(!(key.charAt(0) === '$' && key.charAt(1) === '$')) {
dst[key] = src[key];
}
}
}
return dst || src;
}
provide(angular.module('angular-bem'));
}
);
modules.require(['angular-bem', 'jquery', 'identify'], function(ng, j, id){
window.$ = j;
angular.module('app', ['angular-bem'])
.controller('appController', function AppController(){
var vm = this;
vm.hello = 'Hello, World';
vm.select = [2];
vm.id = id;
vm.llog = [];
vm.items = ['qew','ads','czx','sdf','wtr2qwy'];
vm.log = function(l){
console.log(l);
vm.llog.push(l);
};
});
angular.bootstrap(document, ['app']);
});
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<title>AngularJS Plunker</title>
<link data-require="bem-components@2.2.0" data-semver="2.3.0" rel="stylesheet" href="https://yastatic.net/bem-components/2.3.0/desktop/bem-components.css" />
<script data-require="bem-components@2.2.0" data-semver="2.3.0" src="https://yastatic.net/bem-components/2.3.0/desktop/bem-components.js+bemhtml.js"></script>
<script>document.write('<base href="' + document.location + '" />');</script>
<link rel="stylesheet" href="style.css" />
<script data-require="angular.js@1.4.x" src="https://code.angularjs.org/1.4.3/angular.js" data-semver="1.4.3"></script>
<script src="app.js"></script>
</head>
<body ng-controller="appController as vm">
<ng-bem ng-cloak="">
[
{
block : 'menu',
mods : {
theme : 'islands',
mode: 'radio',
size : 'xl'
},
val:'qew',
attrs : {
'ng-model' : 'vm.menuVal',
'ng-change' : 'vm.log("menu changed")'
},
content: [{
block : 'menu-item',
attrs : {
'ng-repeat': 'item in vm.items'
},
val : '{{item}}',
content : '{{item}}'
}]
},
{
block : 'input',
mods : {
theme : 'islands',
size : 'xl',
angular : true
},
attrs : {
'ng-model' : 'vm.hello',
'ng-change' : 'vm.log("input changed")'
}
},
{
block : 'button',
mods : {
theme : 'islands',
size : 'xl'
},
text: 'Prepend',
attrs : {
'ng-click' : 'vm.items.unshift(vm.hello); vm.hello=vm.id()'
}
}, {
block : 'button',
mods : {
theme : 'islands',
size : 'xl'
},
text: 'Append',
attrs : {
'ng-click' : 'vm.items.push(vm.hello); vm.hello=vm.id()'
}
}
]
</ng-bem>
<p ng-cloak="">menuVal: {{vm.menuVal}}</p>
<button ng-click="vm.menuVal=vm.items[3]">select 4th item</button>
<p ng-cloak="">{{vm.hello}}</p>
<p ng-cloak="">{{vm.llog}}</p>
</body>
</html>
/* Put your css in here */