2013-04-20 5 views

Odpowiedz

0

Można to zrobić w bardziej zgrabny sposób za pomocą AJAX i JSON ActionResult.

<button /> 
<label for="gender"></label> 

<script type="text/javascript"> 
    $("button").click(function() { 
     $('label[for=gender]').load('@Url.Action("ResourceLabel", new { labelKey = "Gender" })'); 
    }); 
</script> 

And stronie serwera, znacznie uproszczone, ale masz pomysł:

public ContentResult ResourceLabel(string labelKey) { 
    return Content(ResourceClass.GetString(labelKey)); 
} 
+2

Czy nie utworzymy osobnego żądania dla serwera dla etykiety EACH? –

+0

Będzie; są lepsze odpowiedzi na stronie dla wielu etykiet. Zostawię to tutaj jako dowód koncepcji dla jednej wytwórni. –

2

chciałbym zrobić coś jak następuje:

<script type="text/javascript"> 
    var resourceStrings = { 
     @foreach (var resource in ViewBag.Resources) 
     { 
      { '@resource.Key' : '@resource.Value' }, 
     } 
    }; 
</script> 

ta zakłada, że ​​już utworzony słownik klucz/wartości zasobów i ustaw właściwość worka widoku ze słownikiem. Możesz wtedy uzyskać dostęp do tych zasobów jako odnośnik do obiektów javascript.

$('label[name=gender]').html(resourceStrings['gender']); 

Można mieć potencjalnie słownika słowników jeśli chcesz uzyskać dostęp do kluczy przez kulturę:

$('label[name=gender]').html(resourceStrings['en_US']['gender']); 
7

Rozwiązanie Użyłem jest użycie Razor utworzyć obiekt JSON, który zawiera wszystkie ciągi zasobów dla danego obszaru zastosowania, np. "Klienci". Tak:

<script type="text/jscript"> 

@{ 

    ResourceSet resourceSet = JsCustomersRes.ResourceManager.GetResourceSet(CultureInfo.CurrentUICulture, true, true); 
    var sbInitial = " var CustomersResourceObj = {"; 
    var sb = new StringBuilder(sbInitial); 
    var resEnum = resourceSet.GetEnumerator(); 
    while (resEnum.MoveNext()) 
    { 
     if (sb.ToString() != sbInitial) 
     { 
      sb.Append(","); 
     } 
     sb.Append("\"" + resEnum.Key + "\":\"" + resEnum.Value.ToString().Replace("\r\n", "").Replace("\"", "\\\"") + "\""); 
    } 
    sb.Append("}"); 
} 

@(Html.Raw(sb.ToString())); 

pliku zasobów „JsCustomersRes” mogą być umieszczone wraz z szczególny kontroler widzi katalogu lub w udostępnionym katalogu widoku. Powinien mieć "Własne narzędzie" ustawione na "PublicResXFileCodeGenerator" w zaawansowanych właściwościach pliku.

Następnie można uzyskać ciąg zasobów z obiektu json w skrypcie:

var resString = CustomersResourceObj[key]; 

gdzie „klucz” jest kluczem ciąg ciąg zasobów chcesz. Wystarczy dodać maszynę Razor jako częściowy widok do strony układu lub strony zgodnie z wymaganiami i gotowe!

+0

to dobry sposób na zdobycie zasobów. moja sugestia jest taka, że ​​powinieneś mieć klucze w zasobach, które są używane TYLKO w skryptach (klucz zaczynający się od 'script'), więc nie ładujesz wszystkich kluczy z pliku zasobów (wyobraź sobie, że masz plik zasobów o ponad 1000 kluczy) . , więc masz na chwilę coś takiego: if (! ResEnum.Key.StartsWith ('script')) kontynuuj; –

+0

Dobry pomysł! Dzięki :) – davaus

3

Moje rozwiązanie opiera się na tym http://codethug.com/2013/08/02/using-net-resources-in-javascript/ i cytując słowa (autor) Tim Larson:

Nie mamy wiele do zrobienia, aby ustalić, co kultura w użyciu. Przeglądarka internetowa, gdy trafi na serwer, zawiera informacje nagłówkowe pokazujące, jakie kultury obsługuje. ASP.Net automatycznie umieszcza tę informację w CultureInfo.CurrentUICulture. Przekazujemy to do metody GetResourceSet , która zwraca zestaw zasobów, który pasuje do bieżących ustawień przeglądarki.

Tak więc, jeśli przeglądarka jest ustawiona na francuski, zasoby francuskie i tylko zasoby francuskie zostaną zwrócone.

Steep 1. Utwórz plik zasobów RLocalizedText.resx do folderu App_GlobalResources.I stwórz wypełnij go całym ciągiem znaków.

Steep 2. Tworzenie ResourcesController

using System.Web.Mvc; 

namespace PortalACA.Controllers 
{ 
    public class ResourcesController : Controller 
    { 
     // GET: Resources 
     public ActionResult Index() 
     { 
      Response.ContentType = "text/javascript"; 
      return View(); 
     } 
    } 
}

Steep 3. Utwórz Index.cshtml widok z ResourcesController

@using System.Collections 
@using System.Globalization 
@using System.Resources 
@using Resources 
@{ 
    Layout = null; 
    // Get a set of resources appropriate to 
    // the culture defined by the browser 
    ResourceSet resourceSet = 
     @RLocalizedText.ResourceManager.GetResourceSet 
     (CultureInfo.CurrentUICulture, true, true); 
} 

// Define the empty object in javascript 
var Resources = {}; 
@foreach (DictionaryEntry res in resourceSet) 
{ 
    // Create a property on the javascript object for each text resource 
    @:[email protected] = "@Html.Raw(
     HttpUtility.JavaScriptStringEncode(res.Value.ToString()))"; 
}

Choose gdzie chcesz go używać.

Strome 4A (układ). Jeśli chcesz używać go na całej stronie, następnie trzeba umieścić ten odniesienie skryptu na _Layout (wspólny View) na @RenderSection

<script src="@Url.Content("~/Resources/Index")"></script> 
@RenderSection("scripts", required: false) 

Steep 4B (Widok). Jeśli chcesz zobaczyć tylko w niektórych widokach.

@section Scripts 
{ 
    <script src="@Url.Content("~/Resources/Index")"></script> 
} 

Strome 5. Teraz należy go użyć. Wybierz widok, w którym chcesz zobaczyć ciągi w plikach zasobów i umieść ten kod.

@section Scripts 
{ 
    <script> 
    $(document).ready(function() { 
     alert(Resources.General_Excepcion); 
    }); 
    </script> 
} 

To wszystko ludzie! Mam nadzieję, że pomoże to innym!

+0

intellisense nie działa w tym podejściu. – Natiq

1

Wolę utworzyć obiekt Javascript, który ma wszystkie zasoby jako właściwości. Unikaję też tworzenia częściowego widoku. Zamiast tego przekazuję wymagany język jako parametr skryptu. W ten sposób możesz dodać skrypt w szablonie globalnym zamiast dodawać go na każdej stronie.

Zasadniczo mam pomocnika statyczną klasę z poniższej metody statycznej:

public static JavaScriptResult JavascriptResources(ResourceManager manager, string resourceObjectName, CultureInfo culture) 
    { 
     ResourceSet resourceSet = manager.GetResourceSet(culture, true, true); 

     StringBuilder sb = new StringBuilder(); 

     sb.AppendFormat("var {0}=new Object();", resourceObjectName); 

     var enumerator = resourceSet.GetEnumerator(); 
     while (enumerator.MoveNext()) 
     { 
      sb.AppendFormat("{0}.{1}='{2}';", resourceObjectName, enumerator.Key, 
       System.Web.HttpUtility.JavaScriptStringEncode(enumerator.Value.ToString())); 
     } 

     return new JavaScriptResult() 
     { 
      Script = sb.ToString() 
     }; 
    } 

w projekcie Dodałem następujące Kontroler:

public class ResourcesController : Controller 
{ 
    [OutputCache(Duration = 36000, VaryByParam = "lang")] 
    // Duration can be many hours as embedded resources cannot change without recompiling. 
    // For the clients, I think 10 hours is good. 
    public JavaScriptResult Index(string lang) 
    { 
     var culture = new CultureInfo(lang); 
     return Helpers.JavascriptResources(Resources.Client.ResourceManager, 
      "Client", culture); 
    } 
} 

Zauważ, że dodałem parametr dać globalny obiekt javascript dowolną nazwę. W powyższym przykładzie, mogę przejść do tłumaczenia jak to w JS:

alert(Client.Info_Message); 

teraz nazwać ten skrypt, zarejestrować go w domyślnym szablonie (na przykład w ~/Shared/_layout.cshtml)

<script type="text/javascript" src="~/resources/[email protected](ViewBag.Language)"></script> 

Najlepszym Aby to działało, należy utworzyć filtr akcji, aby automatycznie wprowadzić język w ViewData. Można to zrobić tak:

public class LanguageInViewBagAttribute : ActionFilterAttribute 
{ 
    public override void OnActionExecuting(ActionExecutingContext filterContext) 
    { 
     var controller = filterContext.Controller; 
     if (controller != null) 
      controller.ViewBag.Language = Thread.CurrentThread.CurrentCulture.TwoLetterISOLanguageName; 
    } 
} 

Następnie można ozdobić kontrolerów lub czynności z tym w stosownych przypadkach, na przykład:

[LanguageInViewBag] 
public class HomeController : Controller 

lub zarejestruj jako filtr globalnym /App_start/Filters.cs

Uwaga: Moja implementacja zakłada, że ​​użytkownik ustawił na jedną osobę kulturę użytkownika na Thread.CurrentThread.CurrentCulture. W ten sposób filtr akcji zna aktualnie wybrany język.

Powiązane problemy