[英]AngularJS Directive with Transclusion and chunking data
我正在嘗試重新創建一個我在AngularJS中創建的jQuery插件作為指令。 我在翻譯方面遇到了一些問題。
jQuery Widget插件: http : //plnkr.co/edit/xxZIb2DyAere7pBY6qm7?p = preview
AngularJS指令: http ://plnkr.co/edit/N6f5H8oZkpNy5jbVQPgj? p = preview
-
我有一系列用戶喜歡:
[
{ name: 'intellix' }, { name: 'and' }, { name: 'konoro' }, { name: 'kingdom' }, { name: 'are' }, { name: 'awesome' },{ name: 'really!' }
]
我的jQuery小部件將數據分塊,因此它們分為3行並滑動它們......數據被轉換成塊並放入它們自己的容器中,如:
[
[
{ name: 'intellix' }, { name: 'and' }, { name: 'konoro' }
],
[
{ name: 'kingdom' }, { name: 'are' }, { name: 'awesome' }
],
[
{ name: 'really!' }
]
]
作為一名設計師或使用這個小部件的任何人,他們不應該自己將它們分塊,這就是小部件/指令應該是什么,你應該能夠擁有自己的HTML ......類似於:
<flicker delay="1000">
<flicker-row ng-repeat="user in users">
<p>User: {{user.name}}</p>
</flicker-row>
</flicker>
我想要的結果是:
<flicker delay="1000">
<div class="container">
<flicker-row>
<p>User: intellix</p>
</flicker-row>
<flicker-row>
<p>User: and</p>
</flicker-row>
<flicker-row>
<p>User: konoro</p>
</flicker-row>
</div>
<div class="container">
<flicker-row>
<p>User: kingdom</p>
</flicker-row>
<flicker-row>
<p>User: are</p>
</flicker-row>
<flicker-row>
<p>User: awesome</p>
</flicker-row>
</div>
<div class="container">
<flicker-row>
<p>User: really</p>
</flicker-row>
</div>
</flicker>
但ngTransclude
只是將整個HTML循環遍歷並將其置於閃爍指令的模板中。 我想在該指令中創建3個塊,然后循環遍歷這些塊,將HTML打印到這3個容器中。
如何轉換創建范圍,但不是只將整個結果轉儲到模板中?
我試圖在我的控制器中預先將數據分塊並有2個控制器...但是在我的閃爍行指令中,項目還沒有循環,所以我無法處理它們
<flicker delay="1000">
<flicker-row ng-repeat="users in userChunks">
<div class="item" ng-repeat="user in users">
<p>{{user.name}}</p>
</div>
</flicker-row>
</flicker>
使用自定義Transclusion檢查我的解決方案。
JS:
.directive('flicker', function() {
return {
restrict: 'E',
scope: {
collection:"=",
item:"@"
},
transclude: true,
replace:true, //I don't want redundant tag after compilation
template: '<div></div>',//simple template for demonstration.
compile: function (element, attr, linker) {//the linker parameter is for custom translusion
return function (scope, element, attr) {
scope.$watchCollection("collection", function(collection){
var children = element.children();
//check if there are already elements, if so remove its scope
for (i = 0; i < children.length; i++){
children.eq(i).children().eq(0).scope().$destroy();
};
element.html("");//clear old content
var chunks = collection.chunk(3);//hardcode 3 for demonstration, we could pass this to the directive's scope by exposing 1 more property in the scope.
for (i = 0; i < chunks.length; i++) {
var div = angular.element("<div class='container'>");
element.append(div);
for (j=0;j<chunks[i].length;j++){
// create a new scope for every element in the collection.
var childScope = scope.$new();
// pass the current element of the collection into that scope
childScope[scope.item] = chunks[i][j];
linker(childScope, function(clone){
// clone the transcluded element, passing in the new scope.
div.append(clone); // add to DOM
});
}
}
});
};
}
};
})
HTML:
<flicker item="user" collection="users" >
<flicker-row>
<p>U: {{user.name}}</p>
</flicker-row>
</flicker>
閃爍指令有2個參數:
user
。 IMO,在這種情況下,范圍管理應該由<flicker>
負責,因為閃爍決定了如何分塊數據。 <flicker>
的內部html只是動態生成的模板。
如果你需要使用像ng-repeat
這樣的語法。 試試這個:
HTML:
<flicker repeat="user in users" >
<flicker-row>
<p>U: {{user.name}}</p>
</flicker-row>
</flicker>
JS:
.directive('flicker', function() {
return {
restrict: 'E',
transclude: true,
replace:true,
template: '<div></div>',
compile: function (element, attr, linker) {
return function (scope, element, attr) {
var match = attr.repeat.match(/^\s*(.+)\s+in\s+(.*?)\s*$/), //parse the syntax string
itemString = match[1],
collectionString = match[2];
scope.$watchCollection(collectionString, function(collection){
var children = element.children();
//check if there are already elements, if so remove its scope
for (i = 0; i < children.length; i++){
children.eq(i).children().eq(0).scope().$destroy();
};
element.html("");//clear old content
var chunks = collection.chunk(3);
for (i = 0; i < chunks.length; i++) {
var div = angular.element("<div class='container'>");
element.append(div);
for (j=0;j<chunks[i].length;j++){
// create a new scope for every element in the collection.
var childScope = scope.$new();
// pass the current element of the collection into that scope
childScope[itemString] = chunks[i][j];
linker(childScope, function(clone){
// clone the transcluded element, passing in the new scope.
div.append(clone); // add to DOM
});
}
}
});
};
}
};
})
您可以進行“手動”轉換。
看看我的示例: 自定義轉換示例
我剛試過不再發明輪子所以我在我的指令中使用了flicker.js和jquery。 結果是一個易於使用的指令。 希望有用。 演示頁面
在視圖中
<flicker users="users"></flicker>
閃爍的模板:
<section class="flicker">
<article ng-repeat="users in chunks" class="row">
<div class="innerSlider">
<div class="item" ng-repeat="user in users">
<p>U: {{user.name}}</p>
</div>
</div>
</article>
</section>
腳本:
Array.prototype.chunk = function (chunkSize) {
var array = this;
return [].concat.apply([],
array.map(function (elem, i) {
return i % chunkSize ? [] : [array.slice(i, i + chunkSize)];
})
);
};
angular.module('flicker', [])
.controller('FlickerCtrl', function ($scope) {
$scope.users = [
{ name: 'intellix' }, { name: 'are' }, { name: 'konoro' }, { name: 'kingdom' }, { name: 'are' }, { name: 'awesome' }, { name: 'really!' }
];
})
.directive('flicker', function ($timeout) {
return {
restrict: 'E',
replace: false,
scope: {
users: '='
},
templateUrl: 'flicker-template.html',
link: function (scope, element, attrs) {
scope.chunks = scope.users.chunk(3);
$timeout(function () { $('.flicker', element).flicker({}); });
}
};
});
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.