Невозможно отобразить вычисленное свойство с помощью Leaf in Vapor 3
Я пытался визуализировать вычисляемое свойство, используя движок шаблонов Leaf с Vapor 3, но пока не повезло. Если хранится одно и то же свойство, все работает нормально. Если я сделаю его вычисленным, на веб-странице ничего не отобразится. Я могу понять причины, по которым такое решение не будет работать, но я хотел бы знать, есть ли способ заставить его работать.
Код элемента для визуализации:
struct SocialLinkContext: Encodable, CSSStyleable {
let hyperlinkURI: String
let classes: [String]
//let styleClasses: String
init(hyperlinkURI: String, classes: [String]) {
self.hyperlinkURI = hyperlinkURI
self.classes = classes
//self.styleClasses = classes.joined(separator: " ")
}
//Seems not to be supported by Leaf
var styleClasses: String {
return self.classes.joined(separator: " ")
}
}
Часть файла main_page.leaf:
...
<div class="row banner">
<div class="banner-text">
<h1 class="responsive-headline">Hello, world!</h1>
<hr />
</div>
#embed("social_links")
</div>
...
Файл social_links.leaf:
<ul class="social">
#for(socialContext in socialLinks) {
<li>
<a href="#(socialContext.hyperlinkURI)">
<i class="#(socialContext.styleClasses)"></i>
</a>
</li>
}
</ul>
PersonalPageContext для передачи в средство визуализации представлений:
struct PersonalWebPageContext: Encodable {
...
let socialLinks: [SocialLinkContext] = [...]
...
}
И, наконец, контроллер PersonalWebPageViewController:
private func serveWebPage(req: Request) throws -> Future<View> {
return try req.view().render("main_page", PersonalWebPageContext())
}
1 ответ
Это потому что Leaf использует Codable
преобразовать ваш тип контекста в данные, которые Leaf может использовать. Теперь по умолчанию Codable
не кодирует и не декодирует вычисленные свойства. Если вы хотите сделать это, вы должны вручную реализовать encode(to:)
метод.
struct SocialLinkContext: Encodable, CSSStyleable {
let hyperlinkURI: String
let classes: [String]
var styleClasses: String {
return self.classes.joined(separator: " ")
}
init(hyperlinkURI: String, classes: [String]) {
self.hyperlinkURI = hyperlinkURI
self.classes = classes
}
func encode(to encoder: Encoder)throws {
var container = encoder.container(keyedBy: CodingKeys.self)
try container.encode(self.hyperlinkURI, forKey: .hyperlinkURI)
try container.encode(self.classes, forKey: .classes)
try container.encode(self.styleClasses, forKey: .styleClasses)
}
enum CodingKeys: String, CodingKey {
case hyperlinkURI, classes, styleClasses
}
}