GithubHelp home page GithubHelp logo

Comments (9)

dustinmoris avatar dustinmoris commented on July 23, 2024 1

Hi, thanks for reporting this. That is an interesting issue, not sure how to fix it though because after some initial investigation it seems like it is a level of caching in the razor engine. I'll have a closer look over the next few days and see what options I have to provide a better experience.

from giraffe.

nojaf avatar nojaf commented on July 23, 2024 1

Sounds about right. I'll see what I can do and try to come up with a pull request.

from giraffe.

dustinmoris avatar dustinmoris commented on July 23, 2024 1

Thanks for helping me with this project so much! I think this issue can be closed now :)

from giraffe.

nojaf avatar nojaf commented on July 23, 2024

I don't think it's the razor. I noticed similar problems with the htmlEngine as well.
If the razorView has a different model, the page does get a proper refresh.

let getText () =
    let guid = Guid.NewGuid().ToString()
    sprintf "Hello, Giraffe world! %s" guid 

let webApp = 
    choose [
        GET >=>
            choose [
                route "/" >=> razorView "Index.cshtml" { Text = getText () } ;
            ]

Is this an F# thing that if you call functions without arguments or without different argument values the result of the function is cached? Because I'm guessing in strict way calling the function with the same arguments should return the same value.

Are we missing a warbler function somewhere?

from giraffe.

dustinmoris avatar dustinmoris commented on July 23, 2024

Hi, I think it is both. In the case of the html engine you need a warbler, because functions in F# are eagerly evaluated and in the case of razor a warbler will help to evaluate the function every time, but the razor engine will still compile a view only once and changing the cshtml while the application is running will not have an effect.

Try this example:

let warbler f a = f a a

let getName() = Guid.NewGuid().ToString()

let webApp = 
    choose [
        GET >=>
            choose [
                route  "/razor"  >=> razorHtmlView "Person" { Name = getName() }
                route  "/razor2" >=> warbler (fun _ -> razorHtmlView "Person" { Name = getName() })
            ]
        setStatusCode 404 >=> text "Not Found" ]

When you run this application then /razor will always return the same page, no matter what. In contrast /razor2 will return a different GUID every time, but both routes will not display any changes made to the cshtml while the app is running.

from giraffe.

nojaf avatar nojaf commented on July 23, 2024

You're right. The warbler solves the execution issue but razor will still cache the changes.
Perhaps the razor issue should be tackled by configuring DotNetWatch to restart if a *.cshtml changes.

Today I also learned that the html engine should be a function instead of a value.

let index =
    let currentTime = DateTime.Now.ToString("HH:mm:ss.ffffzzz")
    let text = sprintf "Hello %s" currentTime
    html [] [
        head [] []
        body [] [
            h3 [] (rawText text)
        ]
    ]

let indexTwo() =
    let currentTime = DateTime.Now.ToString("HH:mm:ss.ffffzzz")
    let text = sprintf "Hello %s" currentTime
    html [] [
        head [] []
        body [] [
            h3 [] (rawText text)
        ]
    ]

Even with the warbler, the first index result will only be executed once. Which makes sense.

from giraffe.

dustinmoris avatar dustinmoris commented on July 23, 2024

Yeah that's correct. So to sum this up, what do we think are the actions to take away here?

  • Extend the SampleApp with the DotNetWatch to restart on *.cshtml changes
  • Add a warbler function to the API
  • Document that the HtmlEngine views should be functions when it should not be static

Anything else?

from giraffe.

dustinmoris avatar dustinmoris commented on July 23, 2024

Hi, so this seems to work, even without a warbler, because it restarts the app on every cshtml change. You must start the app with dotnet watch run though for it to work.

from giraffe.

nojaf avatar nojaf commented on July 23, 2024

Indeed, you only need the warbler if your model is dynamic.
Ex:

[<CLIMutable>]
type Person =
    {
        Name : string;
        CurrentTime: DateTime;
    }
route  "/razor"      >=> razorHtmlView "Person" { Name = "Razor"; CurrentTime = DateTime.Now }
@model SampleApp.Models.Person
@{ 
    Layout = "_Layout";
}

<div>
    <h3>Hello, @Model.Name</h3>
    <p>Current time: @Model.CurrentTime</p>
</div>
<div>
    @{
        await Html.RenderPartialAsync("Partial");
    }
</div>

from giraffe.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.