我试图创建一个AngularJS指令,用于动态生成堆叠的画布元素,一些"静态"还有一些是由索引生成/计算的。
可以在link-function中访问静态canvas元素(示例代码中的类/ id c-area
),因此我获得了一个画布上下文,但ng-repeat
指令生成的那些不是。
为什么ng-repeat
生成的画布元素不存在(在DOM中)?在生成的HTML代码中,它们是可见的。
为了获得这些画布元素的上下文,需要做些什么/改变?
[编辑] 我发现了这个问题/答案"Calling a function when ng-repeat has finished"。 它可能是一个解决方案,但它更像是一个解决方法/黑客,而不是一个好的和干净的解决方案。的 [/编辑]
这是一个plunker,其中包含一些简化的情况示例,其中包含一些console.log来查看结果。
该指令的JS代码:
var app = angular.module('canvasGroup', []);
app.run(['$templateCache', function($templateCache) {
$templateCache.put('canvasgroup.tpl.html', '<div class="canvas-group" style="position:relative">' +
'<canvas ng-repeat="group in ps.groups" id="group-{{group}}" width="{{ps.width}}" height="{{ps.height}}" class="group group-{{group}}" style="position:absolute;">No canvas support</canvas>' +
'<canvas id="c-area" class="c-area" width="{{ps.width}}" height="{{ps.height}}" style="position:absolute;">No canvas support</canvas>' +
'</div>');
}]);
function canvasgroupDirectiveController() {
var ps = this;
ps.groups = [1, 2];
ps.width = 400;
ps.height = 300;
}
app.directive('canvasGroup', function() {
return {
restrict: 'E',
templateUrl: 'canvasgroup.tpl.html',
controller: canvasgroupDirectiveController,
controllerAs: 'ps',
bindToController: {
groups: '='
},
link: function(scope, element, attrs, canvasGroupCtrl) {
var canvasArea = document.getElementsByClassName('c-area');
console.log("canvasArea", canvasArea); // [canvas#c-area.c-area, c-area: canvas#c-area.c-area]
var ctxCanvasArea = canvasArea[0].getContext('2d');
console.log("ctxCanvasArea", ctxCanvasArea); // CanvasRenderingContext2D {}
var group_1_el = element[0].getElementsByClassName('group-1');
console.log("group_1_el", group_1_el);// [] empty objekt
console.log("group_1_el[0]", group_1_el[0]); // undefined
var group_1_doc = document.getElementsByClassName('group-1');
console.log("group_1_doc", group_1_doc);// [] empty objekt
console.log("group_1_doc[0]", group_1_doc[0]); // undefined
//var ctxCanvasGroup = group_1_doc[0].getContext('2d'); // TypeError: Cannot read property 'getContext' of undefined
//console.log("ctxCanvasGroup", ctxCanvasGroup);
}
}
});
答案 0 :(得分:0)
解决方案选择将整个链接功能部分包含(“转换”)到$timeout
函数中,如下所示:
link: function(scope, element, attrs, canvasGroupCtrl) {
$timeout(function() {
var canvasArea = document.getElementsByClassName('c-area');
console.log("canvasArea", canvasArea); // [canvas#c-area.c-area, c-area: canvas#c-area.c-area]
var ctxCanvasArea = canvasArea[0].getContext('2d');
console.log("ctxCanvasArea", ctxCanvasArea); // CanvasRenderingContext2D {}
var group_1_el = element[0].getElementsByClassName('group-1');
console.log("group_1_el", group_1_el); // HTMLCollection[canvas#group-1.group.group-1]
console.log("group_1_el[0]", group_1_el[0]); // <canvas id="group-1" class="group group-1" style="position:absolute;" height="300" width="400" ng-repeat="group in ps.groups">
var group_1_doc = document.getElementsByClassName('group-1');
console.log("group_1_doc", group_1_doc); // HTMLCollection[canvas#group-1.group.group-1]
console.log("group_1_doc[0]", group_1_doc[0]); // <canvas id="group-1" class="group group-1" style="position:absolute;" height="300" width="400" ng-repeat="group in ps.groups">
var ctxCanvasGroup = group_1_doc[0].getContext('2d');
console.log("ctxCanvasGroup", ctxCanvasGroup); // CanvasRenderingContext2D {}
});
}
如果这是一个好/最好的解决方案?我无法说出正确的知识,但它给出了想要的行为。 也许某人有更优雅的方法来解决这个问题,或者可以说明上述解决方案可能存在哪些缺点?
这是更新的plunker