working Usando Razor dentro de JavaScript




use razor in javascript file (10)

¿Es posible o existe una solución alternativa para usar la sintaxis de Razor en JavaScript que está en una vista ( cshtml )?

Estoy tratando de agregar marcadores a un mapa de Google ... Por ejemplo, probé esto, pero obtengo un montón de errores de compilación:

<script type="text/javascript">

    // Some JavaScript code here to display map, etc.

    // Now add markers
    @foreach (var item in Model) {

        var markerlatLng = new google.maps.LatLng(@(Model.Latitude), @(Model.Longitude));
        var title = '@(Model.Title)';
        var description = '@(Model.Description)';
        var contentString = '<h3>' + title + '</h3>' + '<p>' + description + '</p>'

        var infowindow = new google.maps.InfoWindow({
            content: contentString
        });

        var marker = new google.maps.Marker({
            position: latLng,
            title: title,
            map: map,
            draggable: false
        });

        google.maps.event.addListener(marker, 'click', function () {
            infowindow.open(map, marker);
        });
    }
</script>

Eso funcionará bien, siempre y cuando esté en una página CSHTML y no en un archivo JavaScript externo.

Al motor de plantillas Razor no le importa lo que está generando y no distingue entre <script> u otras etiquetas.

Sin embargo, debe codificar sus cadenas para evitar ataques XSS .


La siguiente solución me parece más precisa que combinar JavaScript con Razor. Mira esto: https://github.com/brooklynDev/NGon

Puede agregar casi cualquier información compleja a ViewBag.Ngon y acceder a ella en JavaScript

En el controlador:

public class HomeController : Controller
{
    public ActionResult Index()
    {
        var person = new Person { FirstName = "John", LastName = "Doe", Age = 30 };
        ViewBag.NGon.Person = person;
        return View();
    }
}

En JavaScript:

<script type="text/javascript">
    $(function () {
        $("#button").click(function () {
            var person = ngon.Person;
            var div = $("#output");
            div.html('');
            div.append("FirstName: " + person.FirstName);
            div.append(", LastName: " + person.LastName);
            div.append(", Age: " + person.Age);
        });
    });
</script>

Permite cualquier objeto CLR antiguo (POCO) que pueda ser serializado usando el JavascriptSerializer predeterminado.


Estás intentando atascar una clavija cuadrada en un agujero redondo.

Razor fue pensado como un lenguaje de plantilla que genera HTML. Es muy posible que logres que genere código JavaScript, pero no fue diseñado para eso.

Por ejemplo: ¿Qué pasa si Model.Title contiene un apóstrofe? Eso rompería tu código JavaScript, y Razor no lo escapará correctamente de manera predeterminada.

Probablemente sería más apropiado usar un generador de cadenas en una función auxiliar. Es probable que haya menos consecuencias involuntarias de ese enfoque.


Finalmente encontré la solución (* .vbhtml):

function razorsyntax() {
    /* Double */
    @(MvcHtmlString.Create("var szam =" & mydoublevariable & ";"))
    alert(szam);

    /* String */
    var str = '@stringvariable';
    alert(str);
}

Ninguna de las soluciones anteriores funcionó correctamente ... He intentado todas las formas, pero no me dio el resultado esperado ... Por fin descubrí que hay algunos errores en el código ... Y se da el código completo abajo.

<script type="text/javascript">

    var map = new google.maps.Map(document.getElementById('map'), {
        zoom: 10,
        center: new google.maps.LatLng(23.00, 90.00),
        mapTypeId: google.maps.MapTypeId.ROADMAP
    });

    @foreach (var item in Model)
    {
        <text>
            var markerlatLng = new google.maps.LatLng(@(item.LATITUDE), @(item.LONGITUDE));
            var title = '@(item.EMP_ID)';
            var description = '@(item.TIME)';
            var contentString = '<h3>' + "Employee " +title+ " was here at "+description+ '</h3>' + '<p>'+" "+ '</p>'

            var infowindow = new google.maps.InfoWindow({
                // content: contentString
            });

            var marker = new google.maps.Marker({
                position: markerlatLng,
                title: title,
                map: map,
                draggable: false,
                content: contentString
            });

            google.maps.event.addListener(marker, 'click', (function (marker) {
                return function () {
                    infowindow.setContent(marker.content);
                    infowindow.open(map, marker);
                }
            })(marker));
        </text>
    }
</script>

Acabo de escribir esta función de ayuda. Póngalo en App_Code/JS.cshtml :

@using System.Web.Script.Serialization
@helper Encode(object obj)
{
    @(new HtmlString(new JavaScriptSerializer().Serialize(obj)));
}

Luego, en tu ejemplo, puedes hacer algo como esto:

var title = @JS.Encode(Model.Title);

Fíjate en cómo no pongo comillas a su alrededor. Si el título ya contiene comillas, no explotará. ¡Parece manejar los diccionarios y objetos anónimos muy bien también!


Un simple y un buen ejemplo directo:

<script>
    // This gets the username from the Razor engine and puts it
    // in JavaScript to create a variable I can access from the
    // client side.
    //
    // It's an odd workaraound, but it works.
    @{
        var outScript = "var razorUserName = " + "\"" + @User.Identity.Name + "\"";
    }
    @MvcHtmlString.Create(outScript);
</script>

Esto crea una secuencia de comandos en su página en la ubicación donde coloca el código anterior, que se parece a lo siguiente:

<script>
    // This gets the username from the Razor engine and puts it
    // in JavaScript to create a variable I can access from
    // client side.
    //
    // It's an odd workaraound, but it works.

    var razorUserName = "daylight";
</script>

Ahora tiene una variable de JavaScript global llamada razorUserName que puede acceder y usar en el cliente. El motor de Razor obviamente extrajo el valor de @User.Identity.Name (variable del lado del servidor) y lo puso en el código que escribe en su etiqueta de script.


Una cosa para agregar: descubrí que el compilador de sintaxis Razor (y probablemente el compilador) interpreta la posición del corchete de apertura de manera diferente:

<script type="text/javascript">
    var somevar = new Array();

    @foreach (var item in items)
    {  // <----  placed on a separate line, NOT WORKING, HILIGHTS SYNTAX ERRORS
        <text>
        </text>
    }

    @foreach (var item in items) {  // <----  placed on the same line, WORKING !!!
        <text>
        </text>
    }
</script>

Prefiero "<! -" "> como un" texto> "

<script type="text/javascript">
//some javascript here     

@foreach (var item in itens)
{                 
<!--  
   var title = @(item.name)
    ...
-->

</script>

También hay una opción más que @: y <text></text> .

Usando el bloque <script> sí.

Cuando necesites hacer grandes trozos de JavaScript dependiendo del código de Razor, puedes hacerlo así:

@if(Utils.FeatureEnabled("Feature")) {
    <script>
        // If this feature is enabled
    </script>
}

<script>
    // Other JavaScript code
</script>

Las ventajas de esta manera es que no mezcla demasiado JavaScript y Razor, porque mezclarlos mucho causará problemas de legibilidad en el futuro. También los bloques de texto grandes tampoco son muy legibles.





razor