예제 #1
0
 static TodoAppState SetVisibility(TodoAppState state, SetVisibility act)
 {
     return(new TodoAppState
     {
         Todos = state.Todos,
         Visibility = act.Visibility,
         DescriptionInput = state.DescriptionInput
     });
 }
예제 #2
0
 static TodoAppState UpdateDescriptionInput(TodoAppState state, UpdateDescriptionInput act)
 {
     return(new TodoAppState
     {
         Todos = state.Todos,
         Visibility = state.Visibility,
         DescriptionInput = act.Description
     });
 }
예제 #3
0
 public static ReduxReducer <TodoAppState> Reducer(TodoAppState initialState) =>
 BuildReducer.For <TodoAppState>()
 .WhenActionHasType <AddTodo>(AddTodo)
 .WhenActionHasType <DeleteTodo>(DeleteTodo)
 .WhenActionHasType <UpdateTodo>(UpdateTodo)
 .WhenActionHasType <ToggleTodoCompleted>(ToggleTodoCompleted)
 .WhenActionHasType <SetVisibility>(SetVisibility)
 .WhenActionHasType <UpdateDescriptionInput>(UpdateDescriptionInput)
 .WhenStateIsUndefinedOrNull(() => initialState)
 .WhenActionIsUnknown(state => state)
 .Build();
예제 #4
0
        static TodoAppState ToggleTodoCompleted(TodoAppState state, ToggleTodoCompleted act) => new TodoAppState
        {
            Todos = state.Todos.Select(todo =>
            {
                if (todo.Id == act.Id)
                {
                    return(new Todo
                    {
                        Id = todo.Id,
                        Description = todo.Description,
                        IsCompleted = !todo.IsCompleted
                    });
                }
                else
                {
                    return(todo);
                }
            }).ToArray(),

            Visibility       = state.Visibility,
            DescriptionInput = state.DescriptionInput
        };
예제 #5
0
        private static TodoAppState AddTodo(TodoAppState state, AddTodo act)
        {
            int nextId = 0;

            if (state.Todos.Any())
            {
                var maxId = state.Todos.Max(_todo => _todo.Id);
                nextId = maxId + 1;
            }

            var todo = new Todo
            {
                Id          = nextId,
                Description = state.DescriptionInput,
                IsCompleted = false
            };

            return(new TodoAppState
            {
                Todos = state.Todos.Concat <Todo>(new Todo[] { todo }).ToArray(),
                Visibility = state.Visibility,
                DescriptionInput = state.DescriptionInput
            });
        }
예제 #6
0
 static TodoAppState DeleteTodo(TodoAppState state, DeleteTodo act) => new TodoAppState
 {
     Todos            = state.Todos.Where(todo => todo.Id != act.Id).ToArray(),
     Visibility       = state.Visibility,
     DescriptionInput = state.DescriptionInput
 };
예제 #7
0
        public static void Main()
        {
            var initialState = new TodoAppState
            {
                DescriptionInput = "",
                Visibility       = TodoVisibility.All,
                Todos            = new Todo[]
                {
                    new Todo
                    {
                        Id          = 0,
                        Description = "Have fun with Ractive and Redux",
                        IsCompleted = true
                    },
                    new Todo
                    {
                        Id          = 1,
                        Description = "Make an awesome todo app",
                        IsCompleted = false
                    }
                }
            };

            var store = Redux.CreateStore(Todos.Reducer(initialState));

            Action <TodoVisibility> show = filter => store.Dispatch(new SetVisibility {
                Visibility = filter
            });

            // events that are attached to button clicks on the template
            var eventHandlers = new EventHandlers
            {
                ToggleTodo = id => store.Dispatch(new ToggleTodoCompleted {
                    Id = id
                }),
                DeleteTodo = id => store.Dispatch(new DeleteTodo {
                    Id = id
                }),
                AddTodo        = () => store.Dispatch(new AddTodo {
                }),
                ShowAll        = () => show(TodoVisibility.All),
                ShowComplete   = () => show(TodoVisibility.Completed),
                ShowIncomplete = () => show(TodoVisibility.YetToComplete)
            };

            // functions that can be called in the template to compute smth directly
            var functions = new TemplateFunctions
            {
                Filter = (visibility, todos) =>
                {
                    if (visibility == TodoVisibility.Completed)
                    {
                        return(todos.Where(todo => todo.IsCompleted).ToArray());
                    }
                    if (visibility == TodoVisibility.YetToComplete)
                    {
                        return(todos.Where(todo => !todo.IsCompleted).ToArray());
                    }
                    return(todos);
                }
            };


            var ractive = new Ractive(new RactiveOptions
            {
                Element  = "#app",
                Template = "#app-template",
                Data     = JS.Merge(initialState, functions)
            });

            // although two-way binding is available in Ractive,
            // I will use a vanilla handler to make data-flow one directional
            ractive.Find("#txtAddTodo").OnTextChanged(input =>
            {
                store.Dispatch(new UpdateDescriptionInput {
                    Description = input
                });
            });

            // attach the events
            ractive.On(eventHandlers);

            store.Subscribe(() =>
            {
                var state = store.GetState();
                ractive.Set(JS.Merge(state, functions));
            });
        }