我的目的是创建一个可以将其子元素重新排列(不重新排序)到Bootstrap CSS Grid中的指令,但是我在访问子元素时遇到了很多困难。
我尝试过很多不同的东西,并研究过Compile vs Link vs Controller指令选项。我想我可能不得不在我的指令中将'compile'更改为'link'以使其工作,但我不确定该怎么做。
我有一个AngularJS directive on GitHub,它接受一个数组或参数对象来渲染一个简单或复杂的网格。
在下面的示例中,您可以看到layoutOptions.data = [3, 4]
,这意味着网格将在顶行中有3个单元格,在第二行中有4个单元格。这很有效。
第二步是我想将一些div作为指令的子元素呈现,并且指令将在创建时将它们放置在网格的单元格中。这由layoutOptions.content = ['apple', 'orange', 'pear', 'banana', 'lime', 'lemon', 'grape']
显示,但这需要解耦,以便它可以是任何东西。
<div ng-app="blerg">
<div ng-controller="DemoCtrl">
<div class="container" hr-layout="layoutOptions">
<div ng-transclude ng-repeat="fruit in layoutOptions.content">{{fruit}}</div>
</div>
</div>
</div>
实际输出如下,但不包括带有水果名称的内部DIV
<div class="container hr-layout" hr-layout="layoutOptions">
<div class="row">
<div class="col-md-4"><!-- from ng-repeat --><div>apple</div></div>
<div class="col-md-4"><!-- from ng-repeat --><div>orange</div></div>
<div class="col-md-4"><!-- from ng-repeat --><div>pear</div></div>
</div>
<div class="row">
<div class="col-md-3"><!-- from ng-repeat --><div>banana</div></div>
<div class="col-md-3"><!-- from ng-repeat --><div>lime</div></div>
<div class="col-md-3"><!-- from ng-repeat --><div>lemon</div></div>
<div class="col-md-3"><!-- from ng-repeat --><div>grape</div></div>
</div>
</div>
在这里使用它的jsFiddle:http://jsfiddle.net/harryhobbes/jJDZv/show/
angular.module('blerg', [])
.controller('DemoCtrl', function($scope, $timeout) {
$scope.layoutOptions = {
data: [3, 4],
content: ['apple', 'orange', 'pear', 'banana', 'lime', 'lemon', 'grape']
};
})
.directive("hrLayout", [
"$compile", "$q", "$parse", "$http", function ($compile, $q, $parse, $http) {
return {
restrict: "A",
transclude: true,
compile: function(scope, element, attrs) {
//var content = element.children();
return function(scope, element, attrs) {
var contentCount = 0;
var renderTemplate = function(value, content) {
if (typeof content === 'undefined' || content.length <= contentCount)
var cellContent = 'Test content(col-'+value+')';
else if (Object.prototype.toString.call(content) === '[object Array]')
var cellContent = content[contentCount];
else
var cellContent = content;
contentCount++;
return '<div class="col-md-'+value+'">'+cellContent+'</div>';
};
var renderLayout = function(values, content) {
var renderedHTML = '';
var rowCnt = 0;
var subWidth = 0;
angular.forEach(values, function(value) {
renderedHTML += '<div class="row">';
if(Object.prototype.toString.call(value) === '[object Array]') {
angular.forEach(value, function(subvalue) {
if(typeof subvalue === 'object') {
renderedHTML += renderTemplate(
subvalue.w.substring(4), renderLayout(subvalue.d)
);
} else {
renderedHTML += renderTemplate(subvalue.substring(4));
}
});
} else {
if(value > 12) {
value = 12;
} else if (value <= 0) {
value = 1;
}
subWidth = Math.floor(12 / value);
for (var i=0; i< value-1; i++) {
renderedHTML += renderTemplate(subWidth);
}
renderedHTML += renderTemplate((12-subWidth*(value-1)));
}
renderedHTML += '</div>';
rowCnt++;
});
return renderedHTML;
};
scope.$watch(attrs.hrLayout, function(value) {
element.html(renderLayout(value.data));
});
element.addClass("hr-layout");
};
}
};
}]);
答案 0 :(得分:0)
你的方法看起来太复杂了。也许您应该每次使用 ngRepeat 指令http://docs.angularjs.org/api/ng.directive:ngRepeat和 orderBy 过滤http://docs.angularjs.org/api/ng.filter:orderBy时更新元素的html strong> hrLayout 已更新?
答案 1 :(得分:0)
这可能有所帮助 - http://jsfiddle.net/PwNZ5/1/
App.directive('hrLayout', function($compile) {
return {
restrict: 'A',
// allows transclusion
transclude: true,
// transcludes the content of an element on which hr-layout was placed
template: '<div ng-transclude></div>',
compile: function(tElement, tAttrs, transcludeFn) {
return function (scope, el, tAttrs) {
var data = scope.$eval(tAttrs.hrLayout),
dom = '';
transcludeFn(scope, function cloneConnectFn(cElement) {
// hide the transcluded content
tElement.children('div[ng-transclude]').hide();
// http://ejohn.org/blog/how-javascript-timers-work/
window.setTimeout(function() {
for(var row = 0; row < data.data.length; row++) {
dom+= '<div class="row">';
for(var col = 0; col < data.data[row]; col++) {
dom+= '<div class="col-md-' + data.data[row] + '">' + tElement.children('div[ng-transclude]').children(':eq(' + ( row + col ) + ')').html() + '</div>';
}
dom+= '</div>';
}
tElement.after(dom);
}, 0);
});
};
}
};
});