Recompensa
Já faz um tempo e ainda tenho algumas perguntas pendentes. Espero que, adicionando uma recompensa, talvez essas perguntas sejam respondidas.
- Como você usa ajudantes de html com knockout.js
Por que o documento estava pronto para fazê-lo funcionar (consulte a primeira edição para obter mais informações)
Como faço algo assim se estou usando o mapeamento de nocaute com meus modelos de exibição? Como não tenho uma função devido ao mapeamento.
function AppViewModel() { // ... leave firstName, lastName, and fullName unchanged here ... this.capitalizeLastName = function() { var currentVal = this.lastName(); // Read the current value this.lastName(currentVal.toUpperCase()); // Write back a modified value };
Eu quero usar plug-ins, por exemplo, eu quero poder reverter observáveis como se um usuário cancelasse uma solicitação, eu quero poder voltar ao último valor. Da minha pesquisa, isso parece ser alcançado por pessoas que criam plugins como editáveis
Como uso algo assim se estou usando mapeamento? Eu realmente não quero ir para um método em que eu tenho no meu mapeamento manual de visão, onde mapeei cada campo MVC viewMode para um campo de modelo KO, pois eu quero o mínimo de javascript embutido possível e isso parece o dobro do trabalho, e isso por que eu gosto desse mapeamento.
Preocupa-me que, para facilitar esse trabalho (usando o mapeamento), eu perca muito poder de KO, mas, por outro lado, preocupo-me com o fato de que o mapeamento manual seja apenas muito trabalhoso e faça com que minhas visualizações contenham informações e informações demais. pode se tornar no futuro mais difícil de manter (por exemplo, se eu remover uma propriedade no modelo MVC, também tenho que movê-la no viewmodel KO)
Correio Original
Estou usando o asp.net mvc 3 e estou olhando para o nocaute, pois parece muito legal, mas estou tendo dificuldade para descobrir como ele funciona com o asp.net mvc, especialmente para ver os modelos.
Para mim agora eu faço algo parecido com isto
public class CourseVM
{
public int CourseId { get; set; }
[Required(ErrorMessage = "Course name is required")]
[StringLength(40, ErrorMessage = "Course name cannot be this long.")]
public string CourseName{ get; set; }
public List<StudentVm> StudentViewModels { get; set; }
}
Eu teria um Vm que possui algumas propriedades básicas como CourseName e terá alguma validação simples em cima dele. O modelo Vm pode conter outros modelos de visualização, se necessário.
Eu passaria esse VM para a View onde usaria ajudantes html para me ajudar a exibi-lo ao usuário.
@Html.TextBoxFor(x => x.CourseName)
Talvez eu tenha alguns loops de foreach ou algo para extrair os dados da coleção de modelos de exibição do aluno.
Então, quando eu serialize array
enviava o formulário, usava o jquery e o enviava para um método de ação do controlador que o vinculava novamente ao viewmodel.
Com o knockout.js, tudo é diferente, pois agora você tem modelos de exibição para ele e, de todos os exemplos que vi, eles não usam auxiliares de html.
Como você usa esses 2 recursos do MVC com o knockout.js?
Encontrei este vídeo e, brevemente (nos últimos minutos do vídeo às 18:48), é uma maneira de usar os modelos de visualização, basicamente, com um script embutido que possui o knockmod.js viewmodel que recebe os valores no ViewModel.
Essa é a única maneira de fazer isso? Que tal no meu exemplo ter uma coleção de modelos de exibição? Preciso ter um loop foreach ou algo para extrair todos os valores e atribuí-lo ao nocaute?
Quanto aos auxiliares de html, o vídeo não diz nada sobre eles.
Essas são as duas áreas que me confundem, já que poucas pessoas parecem falar sobre isso e me deixa confuso sobre como os valores iniciais e tudo estão chegando ao ponto de vista quando qualquer exemplo é apenas um exemplo de valor codificado.
Editar
Estou tentando o que Darin Dimitrov sugeriu e isso parece funcionar (eu tive que fazer algumas alterações no código dele). Não sei por que tive que usar o documento pronto, mas de alguma forma nem tudo estava pronto sem ele.
@model MvcApplication1.Models.Test
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
<script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(function()
{
var model = @Html.Raw(Json.Encode(Model));
// Activates knockout.js
ko.applyBindings(model);
});
</script>
</head>
<body>
<div>
<p>First name: <strong data-bind="text: FirstName"></strong></p>
<p>Last name: <strong data-bind="text: LastName"></strong></p>
@Model.FirstName , @Model.LastName
</div>
</body>
</html>
Eu tive que envolvê-lo em torno de um documento jquery pronto para fazê-lo funcionar.
Eu também recebo este aviso. Não tenho certeza do que se trata.
Warning 1 Conditional compilation is turned off -> @Html.Raw
Então, eu tenho um ponto de partida, acho que pelo menos será atualizado quando eu fizer mais algumas brincadeiras e como isso funciona.
Estou tentando passar pelos tutoriais interativos, mas use o um ViewModel.
Ainda não sei como lidar com essas peças
function AppViewModel() {
this.firstName = ko.observable("Bert");
this.lastName = ko.observable("Bertington");
}
ou
function AppViewModel() {
// ... leave firstName, lastName, and fullName unchanged here ...
this.capitalizeLastName = function() {
var currentVal = this.lastName(); // Read the current value
this.lastName(currentVal.toUpperCase()); // Write back a modified value
};
Editar 2
Consegui descobrir o primeiro problema. Nenhuma pista sobre o segundo problema. Ainda assim. Alguém tem alguma idéia?
@model MvcApplication1.Models.Test
@{
Layout = null;
}
<!DOCTYPE html>
<html>
<head>
<title>Index</title>
<script src="../../Scripts/jquery-1.5.1.js" type="text/javascript"></script>
<script src="../../Scripts/knockout-2.1.0.js" type="text/javascript"></script>
<script src="../../Scripts/knockout.mapping-latest.js" type="text/javascript"></script>
<script type="text/javascript">
$(function()
{
var model = @Html.Raw(Json.Encode(Model));
var viewModel = ko.mapping.fromJS(model);
ko.applyBindings(viewModel);
});
</script>
</head>
<body>
<div>
@*grab values from the view model directly*@
<p>First name: <strong data-bind="text: FirstName"></strong></p>
<p>Last name: <strong data-bind="text: LastName"></strong></p>
@*grab values from my second view model that I made*@
<p>SomeOtherValue <strong data-bind="text: Test2.SomeOtherValue"></strong></p>
<p>Another <strong data-bind="text: Test2.Another"></strong></p>
@*allow changes to all the values that should be then sync the above values.*@
<p>First name: <input data-bind="value: FirstName" /></p>
<p>Last name: <input data-bind="value: LastName" /></p>
<p>SomeOtherValue <input data-bind="value: Test2.SomeOtherValue" /></p>
<p>Another <input data-bind="value: Test2.Another" /></p>
@* seeing if I can do it with p tags and see if they all update.*@
<p data-bind="foreach: Test3">
<strong data-bind="text: Test3Value"></strong>
</p>
@*took my 3rd view model that is in a collection and output all values as a textbox*@
<table>
<thead><tr>
<th>Test3</th>
</tr></thead>
<tbody data-bind="foreach: Test3">
<tr>
<td>
<strong data-bind="text: Test3Value"></strong>
<input type="text" data-bind="value: Test3Value"/>
</td>
</tr>
</tbody>
</table>
Controlador
public ActionResult Index()
{
Test2 test2 = new Test2
{
Another = "test",
SomeOtherValue = "test2"
};
Test vm = new Test
{
FirstName = "Bob",
LastName = "N/A",
Test2 = test2,
};
for (int i = 0; i < 10; i++)
{
Test3 test3 = new Test3
{
Test3Value = i.ToString()
};
vm.Test3.Add(test3);
}
return View(vm);
}
fonte
Respostas:
Eu acho que resumi todas as suas perguntas, se eu perdi alguma coisa, por favor me avise ( Se você pudesse resumir todas as suas perguntas em um só lugar, seria legal =))
Nota. Compatibilidade com o
ko.editable
plug-in adicionadoFaça o download do código completo
Como você usa ajudantes de html com knockout.js
Isso é facil:
Onde:
value: CourseId
indica que você está vinculando avalue
propriedade doinput
controle àCourseId
propriedade do seu modelo e do seu modelo de scriptO resultado é:
Por que o documento estava pronto para fazê-lo funcionar (consulte a primeira edição para obter mais informações)
Ainda não entendo por que você precisa usar o
ready
evento para serializar o modelo, mas parece que ele é simplesmente necessário (para não se preocupar com isso)Como faço algo assim se estou usando o mapeamento de nocaute com meus modelos de exibição? Como não tenho uma função devido ao mapeamento.
Se bem entendi, você precisa anexar um novo método ao modelo KO, bem, é fácil mesclar modelos
Para obter mais informações, na seção Mapeamento de diferentes fontes,
Sobre o aviso que você estava recebendo
Você precisa usar aspas
Compatibilidade com o plug-in ko.editable
Eu pensei que seria mais complexo, mas acontece que a integração é realmente fácil, para tornar seu modelo editável basta adicionar a seguinte linha: (lembre-se de que, neste caso, estou usando um modelo misto, de servidor e adicionar extensão no cliente e o editável simplesmente funciona ... é ótimo):
A partir daqui, você só precisa brincar com suas ligações usando as extensões adicionadas pelo plug-in, por exemplo, tenho um botão para começar a editar meus campos como este e neste botão inicio o processo de edição:
Então eu tenho confirmar e cancelar botões com o seguinte código:
E, finalmente, eu tenho um campo para indicar se os campos estão no modo de edição ou não, isso é apenas para vincular a propriedade enable.
Sobre sua pergunta sobre matriz
Você pode fazer o mesmo com o KO, no exemplo a seguir, criarei a seguinte saída:
Basicamente aqui, você tem duas listas, criadas usando
Helpers
e vinculadas ao KO; elas têm umdblClick
evento vinculado que, quando acionado, remove o item selecionado da lista atual e o adiciona à outra lista, quando você publica noController
no conteúdo de cada lista é enviada como dados JSON e reconectada ao modelo do servidorPepitas:
Scripts externos .
Código do controlador
Modelo
Página CSHTML
Scripts
Nota: Acabei de adicionar estas linhas:
Como quando eu envio o formulário, meus campos são desabilitados e, portanto, os valores não foram transmitidos ao servidor, por isso adicionei alguns campos ocultos para fazer o truque
fonte
ko.editables
plug-in, você pode verificar a resposta atualizada ou se você quiser, você pode baixar todo o projeto para executá-lo localmenteVocê pode serializar seu modelo de exibição do ASP.NET MVC em uma variável javascript:
Existem muitos exemplos na documentação do knockout que você pode analisar.
fonte
Para obter as propriedades computadas adicionais após o mapeamento do servidor, você precisará aprimorar ainda mais seus modelos de exibição no lado do cliente.
Por exemplo:
Portanto, toda vez que você mapeia a partir do JSON bruto, é necessário reaplicar as propriedades calculadas.
Além disso, o plug-in de mapeamento oferece a capacidade de atualizar incrementalmente um modelo de exibição, em vez de recriá-lo toda vez que você vai e volta (use um parâmetro adicional em
fromJS
):E isso executa uma atualização incremental de dados em seu modelo, apenas de propriedades mapeadas. Você pode ler mais sobre isso na documentação de mapeamento
Você mencionou nos comentários sobre a resposta de Darin ao pacote FluentJSON . Sou o autor disso, mas seu caso de uso é mais específico que o ko.mapping. Geralmente, eu o usaria apenas se os seus modelos de exibição fossem de sentido único (ou seja, servidor -> cliente) e, em seguida, os dados fossem postados novamente em algum formato diferente (ou nenhum). Ou se o seu modelo de exibição em javascript precisar estar em um formato substancialmente diferente do modelo do seu servidor.
fonte