如何添加到定义为属性的速度图?
我在添加变量时遇到问题,该变量是作为宏的属性传递的速度图。
考虑以下代码:
#macro ( test $attr )
1 $attr.edd
#set($attr.edd = "edd")
2 $attr.edd
#set($foo = {"bar" : "bar" })
3 $foo.edd
#set($foo.edd = "edd")
4 $foo.edd
#end
#test({"bar" : "bar" })
我期望以下输出:
1 $attr.edd 2 edd 3 $foo.edd 4 edd
但我得到:
1 $attr.edd 2 $attr.edd 3 $foo.edd 4 edd
任何人都可以为我解决这个问题吗?
I have a problem adding to a variable which is a map in velocity that has been passed as an attribute for a macro.
Consider the following code:
#macro ( test $attr )
1 $attr.edd
#set($attr.edd = "edd")
2 $attr.edd
#set($foo = {"bar" : "bar" })
3 $foo.edd
#set($foo.edd = "edd")
4 $foo.edd
#end
#test({"bar" : "bar" })
I would expect the following output:
1 $attr.edd 2 edd 3 $foo.edd 4 edd
But I get:
1 $attr.edd 2 $attr.edd 3 $foo.edd 4 edd
Can anyone solve this issue for me?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
这非常恶心,但我猜测该属性是最终的(考虑到速度处理变量的方式似乎有点奇怪/危险),因此重新定义变量似乎可以解决问题:
我希望其他人会有更好的解决方案。 。
This is pretty gross but I'm guessing the attribute is final (seems a bit odd/dangerous considering the way velocity treats variables) so redefining the variable seems to solve the issue:
I'm hoping someone else will have a better solution...
使用 Map.key 是调用 Map.get(key) 的快捷方式。因此,当您说 $attr.edd 速度实际上是在幕后执行 Map.get("edd") 并返回该地图条目的值。
我认为在您的情况下发生的情况是您试图将字符串“edd”分配给 Map.get(“edd”) 的返回值,这只是一个字符串,而不是对该 Map 条目的引用。由于执行顺序,$attr.edd 在执行等式的 equals 侧之前已经解析为 Map.get("edd") 的返回值。
例如,您所做的只是与以下内容等效的简写:
如果您想更改该条目的值,则需要使用 Map.set("edd", "edd")。我不相信有一种快捷的方法来调用 set,所以你只需像在 java 代码中那样调用 $attr.set("edd", "edd") 即可。
然而,还有另一个警告。 Velocity 不仅仅让您调用返回 void 的方法,因为我们的想法是您使用它来显示属性和值,因此您永远不需要 void 方法。
当我们需要这样做时,我们通过将其分配给一个变量来破解它,我们从不使用
这种 hacky,但速度和 MVC 背后的概念一般是,当事物到达您的视图层时,它们应该填充它们需要的所有内容并被视为只读。然而世界很少如此黑白分明,这种事情有时是必要的。
编辑:
顺便说一句,您将 $foo.edd 设置为“edd”的最后一个示例实际上打印出 edd 的原因并不是因为您已成功更改了数组值,而是因为您创建了一个名为“foo.edd”的新速度变量。 edd”,这是一个字符串。
Using Map.key is a shortcut in velocity to calling Map.get(key). So when you say $attr.edd velocity is really doing Map.get("edd") behind the scenes and returning you a the value of that map entry.
I think what's happening in your case is that you're trying to assign the string "edd" to the return value of Map.get("edd") which is a just a String and not a reference back to that Map entry. Because of the order of execution $attr.edd is already resolved to the return value of Map.get("edd") before the equals side of the equation executed.
For example what you're doing is just the short hand equivalent of the following:
If you want to change the value of that entry you'll need to use Map.set("edd", "edd"). I don't beleive there is a short hand way to call set so you'll just call $attr.set("edd", "edd") as you would in java code.
There is another caveat however. Velocity doesn't just let you call a method that returns void because the idea is you're using it to display properties and values and thus you should never need a void method.
When we need to do this we kind of hack it by assigning it to a variable we never use
Kind of hacky but the concept behind velocity and MVC in general is that by the time things get to your view layer they should populated with everything they need and treated as read only. However the world is seldom so black and white and this sort of thing is sometimes necessary.
EDIT:
BTW, the reason your last example of setting $foo.edd to "edd" actually prints out edd isn't because you've successfully changed the array value, it's because you've created a new velocity variable named "foo.edd" which is a string.