画布仅在地图上绘制循环的最后一个元素

丽塔·迪亚斯(Rita Dias)

我正在使用Icon.Canvas在传单地图上用画布绘制标记。我遇到了一些问题,我认为这与“关闭循环”有关,但是由于创建普通画布及其上下文和我在做什么,我似乎无法使用任何其他解决方案(canvas元素和ctx由Icon.Canvas库创建)。

for (var park in parksMap) {

                var circle = new L.Icon.Canvas({
                    iconSize: new L.Point(50, 50)
                });


                var item = parksMap[park];
                var total = item.kpis.availability.online + item.kpis.availability.offline + item.kpis.availability.noComm;
                var greenSize = item.kpis.availability.online * 2 / total;
                var redSize = item.kpis.availability.offline * 2 / total;

                console.log('OUTSIDE');
                console.log(item);
                circle.draw = function (ctx, w, h) {
                    console.log('INSIDE');
                    console.log(item);

                    setUpParkForStatus(item, ctx, greenSize, redSize);
                    parkWindConstructor(ctx);

                    ctxArray.push({
                        id: item.id,
                        ctx: ctx
                    });
                } ... 

(code continues on to create the actual markers)
}

setUpParksStatus是在图纸中具有实际代码的函数。以下是console.logs的结果,以使您更好地理解:

 OUTSIDE
 park1

 OUTSIDE
 park2

 INSIDE
 park2

 INSIDE
 park2
冬玉

您可以使用IIFE返回包含当前逻辑的函数的a,因此此时的值不会受到循环的影响。

编辑:进入时ES2015,您可以使用let / const代替var当前的代码来实现,block-scoped而不是function-scoped

如果可以使用库,则Underscore.each也可以完成工作,否则,您仍然可以使用Object.keys()获取键as Array,然后使用.forEach它来循环遍历,所有这些方法都可以防止值在循环更改中获得与循环推进。

失败演示和IIFE修复:

'use strict';
var obj = {
  'a': 1,
  'b': 2,
  'c': 3
};
var funcArr1 = [];
var funcArr2 = [];
var k, func1, func2;
for (k in obj) {
  // Way 1, all point to last.
  func1 = function() {
    console.log(k, obj[k]);
  };
  
  // Snapshot it
  // The wrap function will be called imediately, and it'll return the function similar to func1
  // But the outer function creates a scope, which stores the k(and rename it to v to avoid ambiguous)
  // So all the func2s will point to each key in obj instead of last.
  func2 = (function(v) {
    return function() {
      console.log(v, obj[v]);
    };
  })(k);
  
  funcArr1.push(func1);
  funcArr2.push(func2);
}

// IN ES2015, you can use let to achieve:
var funcArr3 = [];
var func3;
// The let, unlike var, is block scoped, so it can achieve what you expect in simpler form.
for (let m in obj) {
  func3 = function() {
    console.log(m, obj[m])
  }; 
  funcArr3.push(func3);
}

// To loop object with .forEach, which works on array.
var funcArr4 = [];
Object.keys(obj).forEach(function(key, index) {
  funcArr4.push(function() {
    console.log(key, obj[key]);
  });
});

var i, length = funcArr1.length;
for (i = 0; i < length; ++i) {
  console.log('Way1');
  funcArr1[i]();   // All of it will log c, 3, as k is pointing to c when exit the loop.
  console.log('Way2');
  funcArr2[i]()  // Because we use a function to keep k, it'll log what we expect.
  
  console.log('Way ES2015');
  funcArr3[i]();  // Because we use a function to keep k, it'll log what we expect.
  console.log('Way forEach');
  funcArr4[i]();  // Because we use a function to keep k, it'll log what we expect.
}

演示forEach

var obj = {
  'a': 1,
  'b': 2,
  'c': 3
};
var funcArr = [];
Object.keys(obj).forEach(function(key, index) {
  funcArr.push(function() {
    console.log(key, obj[key]);
  });
});

var i, length = funcArr.length;
for (i = 0; i < length; ++i) {
  console.log('Way forEach');
  funcArr[i]();  // Because we use a function to keep k, it'll log what we expect.
}

演示用letES2015(这需要一些非常现代化broswer版本的片段工作),但有transpilers是能够编译ES2015语法ES5到大多数浏览器上工作(如:巴别塔):

'use strict';  // This make chrome to accept some ES2015 syntax
const obj = {
  'a': 1,
  'b': 2,
  'c': 3
};
// IN ES2015, you can use let to achieve:
let funcArr = [];
// The let, unlike var, is block scoped, so it can achieve what you expect in simpler form.
for (let m in obj) {
  funcArr.push(function() {
    console.log(m, obj[m])
  });
}

for (let i = 0, len = funcArr.length; i < len; ++i) { 
  console.log('Way ES2015');
  funcArr[i]();  // Because we use a function to keep k, it'll log what we expect.
}

因此,您可以对自己执行类似的操作circle.draw

// Now the current value that may be used by the callback won't change as loop advanced.
circle.draw = (function(item, total, greenSize, redSize) {
  return function (ctx, w, h) {
        console.log('INSIDE');
        console.log(item);

        setUpParkForStatus(item, ctx, greenSize, redSize);
        parkWindConstructor(ctx);

        ctxArray.push({
            id: item.id,
            ctx: ctx
        });
  };
})(item, total, greenSize, redSize);

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

使用 JSON 的 Google 地图标记。地图上仅显示循环中的最后一个标记

使用Polygon在整个地图上绘制一个矩形

insertBefore仅在循环的最后一个元素上附加元素

在最后一个画布上绘制线条

ReactJS从地图上唯一选择一个元素

.push在循环中创建的数组是正确的长度,但仅在重复时推送最后一个元素

使... of跳过循环的最后一个元素

在地图上绘制 df - 两个图而不是一个

为什么事件侦听器仅在for循环中创建的最后一个元素上注册?

为什么仅在最后一个子图上打开网格?

在地图上绘制新圆之前先删除上一个圆

在地图上的一个点周围绘制缓冲区 - RS SF

在地图上绘制特定元素

在最后一个柱形图上绘制值和字符

VBA数组循环未使用最后一个元素

循环JavaScript会跳过最后一个元素

最后一个元素未在循环中删除

如何使用for循环返回列表的最后一个元素

R: for 循环只对最后一个列表元素执行

For循环仅迭代Python中的最后一个元素

For 循环只迭代列表中的最后一个元素

使用列表的最后一个元素直到循环完成

地图仅在Java中返回最后一个数据

Scala-地图功能-仅返回地图的最后一个元素

在地图上进行SASS循环,获取下一个迭代

循环asynctask android仅在循环中执行最后一个值

循环内的.load似乎仅在最后一个循环上触发

Google地图,绘制带有多个标记的路线,隐藏最后一个标记以外的标记

多个具有相同类的元素-仅在最后一个元素之后插入