public MergeResult <TMessage, T> MergeWith(Option <IVDomNode <T, TMessage> > node) { var nodeProperties = node .Some(p => p.Properties) .None(ImmutableList <IVDomNodeProperty> .Empty); var acts = properties .Select(prop => { var existingProp = nodeProperties .OfType <IVDomNodeProperty <T, TMessage> >() .FirstOrDefault(p => p.CanMergeWith(prop)); var apply = prop.MergeWith(existingProp); return(new Func <T, ISub <TMessage> >(o => apply(o))); }) .ToList(); var act = new Func <T, ISub <TMessage> >(o => Sub.Batch(acts.Select(a => a(o)))); return(node .Some(n => new MergeResult <TMessage, T>(o => { var sub = Sub.Batch( o.Some(act).None(Sub.None <TMessage>()), o.Some(subscribe).None(Sub.None <TMessage>()) ); return (None, sub); })) .None(new MergeResult <TMessage, T>(_ => { var t = factory(); var sub = Sub.Batch( subscribe(t), act(t) ); var result = (Some(t), sub); return result; }))); }
public Func <TParent, ISub <TMessage> > MergeWith(IVDomNodeProperty property) { var listProperty = Optional(property) // Use IReadOnlyList<T> instead of IImmutableList<T> because T is covariant for IReadOnlyList .TryCast <IVDomNodeProperty <TParent, TMessage, IReadOnlyList <object> > >(); // can't use IReadOnlyList<IVDomNode<T, TMessage>> because T is not covariant for IVDomNode var items = listProperty .Some(oldProperty => oldProperty.Value) .None(() => ImmutableList <object> .Empty); var replaceActions = Value .Take(items.Count) .Select((value, i) => { var apply = value.MergeWith(Optional(items[i] as IVDomNode <TMessage>)); return(new Func <System.Collections.IList, ISub <TMessage> >(o => { var(p, d) = apply(o[i]); p .IfSome(newItem => { o.RemoveAt(i); o.Insert(i, newItem); }); return d; })); }); var addActions = Value .Skip(items.Count) .Select(value => { var apply = value.MergeWith(None); return(new Func <System.Collections.IList, ISub <TMessage> >(o => { var(p, d) = apply(None); p .IfSome(newItem => o.Add(newItem)); return d; })); }); var removeActions = items .Skip(Value.Count) .Select(_ => { return(new Func <System.Collections.IList, ISub <TMessage> >(o => { o.RemoveAt(o.Count - 1); return Sub.None <TMessage>(); })); }); var actions = replaceActions .Concat(removeActions) .Concat(addActions) .ToList(); var act = new Func <System.Collections.IList, ISub <TMessage> >(o => Sub.Batch(actions.Select(a => a(o)))); return(new Func <TParent, ISub <TMessage> >(o => { return act((System.Collections.IList)propertyInfo.GetValue(o)); })); }
public IVDomNode <T, TMessage> AddSubscription(Func <T, ISub <TMessage> > fn) { return(new VDomNode <T, TMessage>(factory, properties, o => Sub.Batch(subscribe(o), fn(o)))); }