Esempio n. 1
0
        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));
            }));
        }
Esempio n. 3
0
 public IVDomNode <T, TMessage> AddSubscription(Func <T, ISub <TMessage> > fn)
 {
     return(new VDomNode <T, TMessage>(factory, properties, o => Sub.Batch(subscribe(o), fn(o))));
 }