Установка начального значения нокаутирующей viewmodel с помощью razor

#asp.net-mvc-3 #razor #knockout.js

#asp.net-mvc-3 #razor #knockout.js

Вопрос:

Мне кажется странным, что я не могу найти никакой информации о том, как динамически заполнять нокаутирующую viewmodel. Я предполагаю, что мои условия поиска неверны или что-то в этом роде.

В любом случае, поскольку я использую Asp.Net MVC 3 и я собираюсь использовать knockout только для одной конкретной страницы, в этот первый раз я надеялся, что смогу каким-то образом использовать модель Razor для вставки в knockout.

 @Html.TextBoxFor(m => m.PropertyName, new { data_bind = "value: name" })
  

Я понял, что это не сработало, потому что, даже если razor заполняет поле propertyName, это происходит до привязки, поэтому оно не присваивает его значение нокаутирующей viewmodel.

         var viewModel = {
        name: ko.observable(@GetPoertyNameUsingRazorSomehow)
    };
  

Это тоже не работает, по крайней мере, насколько я понимаю.

Поскольку мы можем легко получить данные RazorModel, используя MVC 3 в обычном режиме, я был уверен, что мы каким-то образом сможем внедрить их в Knockout ViewModel. Я не видел никаких руководств, объясняющих, как это сделать. Чего мне не хватает?

Ответ №1:

Я создал небольшую библиотеку поверх Json.NET как раз для такого случая:

https://github.com/paultyng/FluentJson.NET

Вы можете создать JSON в Razor view, подобном этому (обратите внимание на методы расширения Knockout):

 @JsonObject.Create()
    .AddProperty("name", "value")
    .AddProperty("childObject", c => {
        .AddProperty("childProperty", "value2")
    })
    .AddObservable("knockoutProperty", 123)
  

Это привело бы к созданию JSON, подобного этому:

 {"name":"value","childObject":{"childProperty":"value2"},"knockoutProperty":ko.observable(123)}
  

Методы Knockout добавляются с помощью методов расширения, и другие вещи также могут быть легко расширены.

Пакет находится в Nu-Get, если вы этого хотите.

Комментарии:

1. Очень приятно, я новичок во всем этом, поэтому не знаю JSON. Это объект Javascript по умолчанию? Также обрабатывает ли он свойства, являющиеся коллекциями других объектов? Кроме того, что такое команда Nu-Get?

2. PM> Установить пакет fluentjson.net

3. Также существует AddObservableArray метод

4. В настоящее время я расширяю его, чтобы просто позволить вам делать @Knockout.ToViewModel(Model) , и он будет перечислять свойства модели, чтобы упростить часть моего собственного кода, где это просто прямая сериализация модели MVC для модели Knockout, и я не хочу вызывать сопоставление на клиенте.

5. Да, я вроде как ожидал, что кто-то сделает расширение HtmlHelper @Html.ViewModelFor(Model) , а затем также для полей @Html.ValueBoundFOr(m => m.Name)

Ответ №2:

Предполагая, что имя вашего свойства должно быть строкой, это должно сработать, если вы заключите @getpoertynameusingraz каким-либо образом в кавычки. В противном случае вы передаете неопределенный объект в наблюдаемый.

 name: ko.observable('@GetPoertyNameUsingRazorSomehow')
  

Комментарии:

1. Вы уверены, кажется, что синтаксис Razor не работает внутри тега Script.

2. Я не верю, что Intellisense не будет работать в теге script, но вывод должен работать.

3. Неплохо. Это то, что часто используется для заполнения ViewModels или вы можете указать мне на руководство, которое объясняет это?

4. Я думаю, что с точки зрения стандартного использования knockout многие люди вместо этого будут использовать методы отображения fromJS или fromJSON и извлекать данные с сервера с помощью вызовов ajax вместо того, чтобы отправлять их жестко закодированными в представление. Или просто используйте сериализацию json в вашем представлении из вашей модели, поэтому вы не обязательно вручную записываете все свойства.

5. Я пробовал это в MVC3 и MVC4, и intellisense работает в теге script, размещенном в разделе script. Проверьте свой web.config в папке views, чтобы убедиться, что он ссылается на соответствующий материал