简体   繁体   English

无法使用Leaf in Vapor 3渲染计算属性

[英]Cannot render a computed property with Leaf in Vapor 3

I've been trying to render a computed property using the templating engine Leaf with Vapor 3, but so far no luck. 我一直在尝试使用模板引擎Leaf with Vapor 3来渲染计算属性,但到目前为止还没有运气。 If the same property is stored, everything works fine. 如果存储相同的属性,一切正常。 If I make it computed, nothing is displayed in the web page. 如果我进行计算,则网页中不会显示任何内容。 I can understand the reasons why such solution wouldn't be working, but I'd like to know if there's any way to make it working. 我可以理解为什么这样的解决方案不起作用的原因,但我想知道是否有任何方法可以使其工作。

Code for the element to render : 要呈现的元素的代码

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: " ")
    }
}

Part of the main_page.leaf file: main_page.leaf文件的一部分:

...
<div class="row banner">
    <div class="banner-text">
        <h1 class="responsive-headline">Hello, world!</h1>
        <hr />
    </div>
    #embed("social_links")
</div>
...

The social_links.leaf file: social_links.leaf文件:

<ul class="social">
    #for(socialContext in socialLinks) {
        <li>
            <a href="#(socialContext.hyperlinkURI)">
                <i class="#(socialContext.styleClasses)"></i>
            </a>
        </li>
    }
</ul>

The PersonalPageContext to be passed to the View Renderer: 要传递给View Renderer的PersonalPageContext

struct PersonalWebPageContext: Encodable {
    ...
    let socialLinks: [SocialLinkContext] = [...]
    ...
}

And finally, the PersonalWebPageViewController controller: 最后, PersonalWebPageViewController控制器:

private func serveWebPage(req: Request) throws -> Future<View> {
    return try req.view().render("main_page", PersonalWebPageContext())
}

This is because Leaf uses Codable to convert your context type to data that Leaf can use. 这是因为Leaf使用Codable将您的上下文类型转换为Leaf可以使用的数据。 Now by default, Codable does not encode or decode computed properties. 现在默认情况下, Codable 不会对计算属性进行编码或解码。 If you want to do that, you have to manually implement the encode(to:) method. 如果要这样做,则必须手动实现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
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM