Мой аккуратный трюк JavaScript состоит в том, чтобы разделить весь сценарий на две разные функции!
Чтобы подготовить вещи, объявляется одна глобальная переменная и определяется один обработчик событий:
var tTimeout;
element.addEventListener("transitionend", afterTransition, true);//firefox
element.addEventListener("webkitTransitionEnd", afterTransition, true);//chrome
Затем, когда я скрываю элемент, я использую что-то вроде этого:
function hide(){
element.style.opacity = 0;
}
function afterTransition(){
element.style.display = 'none';
}
Для повторного появления элемента я делаю что-то вроде этого:
function show(){
element.style.display = 'block';
tTimeout = setTimeout(timeoutShow, 100);
}
function timeoutShow(){
element.style.opacity = 1;
}
Он работает, пока !
Вы можете сделать JsonConverter
, который делает это в общем виде, используя ContractResolver
для группировки и заполнения свойств в классе, десериализованном или содержащем его классы по мере необходимости.
Вы не запрашивали сериализации, а только десериализацию, так вот что это делает:
public class JsonFlatteningConverter : JsonConverter
{
readonly IContractResolver resolver;
public JsonFlatteningConverter(IContractResolver resolver)
{
if (resolver == null)
throw new ArgumentNullException();
this.resolver = resolver;
}
public override bool CanConvert(Type objectType)
{
return resolver.ResolveContract(objectType) is JsonObjectContract;
}
public override object ReadJson(JsonReader reader, Type objectType, object existingValue, JsonSerializer serializer)
{
if (reader.TokenType == JsonToken.Null)
return null;
JObject jObject = JObject.Load(reader);
var contract = (JsonObjectContract)resolver.ResolveContract(objectType); // Throw an InvalidCastException if this object does not map to a JObject.
existingValue = existingValue ?? contract.DefaultCreator();
if (jObject.Count == 0)
return existingValue;
var groups = jObject.Properties().GroupBy(p => p.Name.Contains('.') ? p.Name.Split('.').FirstOrDefault() : null).ToArray();
foreach (var group in groups)
{
if (string.IsNullOrEmpty(group.Key))
{
var subObj = new JObject(group);
using (var subReader = subObj.CreateReader())
serializer.Populate(subReader, existingValue);
}
else
{
var jsonProperty = contract.Properties[group.Key];
if (jsonProperty == null || !jsonProperty.Writable)
continue;
if (jsonProperty != null)
{
var subObj = new JObject(group.Select(p => new JProperty(p.Name.Substring(group.Key.Length + 1), p.Value)));
using (var subReader = subObj.CreateReader())
{
var propertyValue = serializer.Deserialize(subReader, jsonProperty.PropertyType);
jsonProperty.ValueProvider.SetValue(existingValue, propertyValue);
}
}
}
}
return existingValue;
}
public override bool CanWrite { get { return false; } }
public override void WriteJson(JsonWriter writer, object value, JsonSerializer serializer)
{
throw new NotImplementedException();
}
}
И затем используйте его таким образом:
var resolver = new DefaultContractResolver();
var settings = new JsonSerializerSettings { ContractResolver = resolver, Converters = new JsonConverter[] { new JsonFlatteningConverter(resolver) } };
var person = JsonConvert.DeserializeObject<Person>(json, settings);
Прототип скрипт .