我正在尝试重新创建一个我在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 ......如下: / p>
<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>
答案 0 :(得分:3)
使用自定义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>
闪烁指令有两个参数:
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
});
}
}
});
};
}
};
})
答案 1 :(得分:1)
您可以进行“手动”转换。
看看我的示例:Custom transclude example
答案 2 :(得分:1)
我刚试过不再发明轮子所以我在我的指令中使用了flicker.js和jquery。结果是一个易于使用的指令。希望有用。 DEMO PAGE
在视图中
<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({}); });
}
};
});