При регистрации продукта пользователь может настроить его URL!Когда пользователь наберет Tipo de produto
, Nome
или Link
, веб-сайт покажет вам, как будет выглядеть URL для этого продукта
Полныйurl: http://i.stack.imgur.com/jZg7G.png
Обратите внимание, что поле "Tipo de produto" также изменяет URL-адрес !!
Для этого я создал помощника в KnockoutJS
Код
KnockoutJS
ko.bindingHandlers.url =
update: (element, valueAccessor, allBindingsAccessor, viewModel) ->
link = ko.utils.unwrapObservable(valueAccessor())
if link
link = link.toLowerCase().trim().replaceAll(" ", "-")
link = encodeURI(link)
else
link = ""
valueAccessor()(link)
$(element).nextAll(".link-exibicao").text(link).effect("highlight", { color: "#FDBB30" }, 800 )
Единственная цель этого помощника - создать действительный URL-адрес и отобразить его в диапазоне .link-exibicao
ViewModel
public class ProdutoViewModel
{
[AdditionalMetadata("data-bind", "event: { change: function(data) { Link(data.Nome()); }}")]
public string Nome { get; set; }
[DataType(DataType.Url)]
[AdditionalMetadata("Prefixo", "Produto/")]
public string Link { get; set; }
[Display(Name = "Descrição")]
[DataType(DataType.MultilineText)]
public string Descricao { get; set; }
public int? Ordem { get; set; }
}
AdditionalMetadata
добавит атрибут с этим именем и значением.Например, свойство Name
сгенерирует HTML-код:
<input data-bind="value: Nome, event: { change: function(data) { Link(data.Nome()); }}" id="Nome" name="Nome" type="text" value="">
Url.cshtml
Следующим шагом будет добавление разметки data-bind="url: Link"
ввсе поля типа URL:
@model string
@{
var values = ViewData.ModelMetadata.AdditionalValues;
object objDatabind;
string data_bind = "";
if (values.TryGetValue("data-bind", out objDatabind))
{
data_bind = objDatabind.ToString();
}
var nomeCampo = Html.IdForModel();
var objPrefixo = values["Prefixo"];
string prefixo = objPrefixo.ToString();
string separador = "/";
if (!string.IsNullOrWhiteSpace(prefixo))
{
if (prefixo.EndsWith("/") || prefixo.EndsWith("#"))
{
separador = prefixo[prefixo.Length - 1].ToString();
prefixo = prefixo.Substring(0, prefixo.Length - 1);
}
}
}
@Html.TextBoxFor(p => Model, new { data_bind = "value: " + nomeCampo + ", url: " + nomeCampo + (string.IsNullOrWhiteSpace(data_bind) ? "" : ", " + data_bind) })
@Request.Url.Host/<span class="link-prefixo">@prefixo</span><span class="link-separador">@separador</span><span class="link-exibicao"></span>
ProdutoViewModel.cshtml
Наконец, и самым простым шагом будет создание формы =):
<div class="editor-label">
<label>Tipo de produto</label>
</div>
<div class="editor-field">
<select data-bind="options: Tipos, optionsText: 'Nome', value: TipoSelecionado, optionsCaption: 'Selecione...'"></select>
</div>
<div class="editor-label">
@Html.LabelFor(p => p.Nome)
</div>
<div class="editor-field">
@Html.EditorFor(p => p.Nome)
@Html.ValidationMessageFor(p => p.Nome)
</div>
<div class="editor-label">
@Html.LabelFor(p => p.Link)
</div>
<div class="editor-field">
@Html.EditorFor(p => p.Link)
@Html.ValidationMessageFor(p => p.Link)
</div>
<div class="editor-label">
@Html.LabelFor(p => p.Descricao)
</div>
<div class="editor-field">
@Html.EditorFor(p => p.Descricao)
@Html.ValidationMessageFor(p => p.Descricao)
</div>
<div class="editor-label">
@Html.LabelFor(p => p.Ordem)
</div>
<div class="editor-field">
@Html.EditorFor(p => p.Ordem)
@Html.ValidationMessageFor(p => p.Ordem)
</div>
Проблема
Всякий раз, когда набираются простые слова, такие как: «название моего продукта», все работает отлично!
Но такие слова, как meu prodúto côm açênto
, отображается сообщение об ошибке ниже
Uncaught Error: Unable to parse bindings.
Message: RangeError: Maximum call stack size exceeded;
Bindings value: value: Link, url: Link