Пример #1
0
        private void OnJumpToState(object sender, JumpToStateCallback e)
        {
            SequenceNumberOfCurrentState = e.payload.actionId;
            using (Store.BeginInternalMiddlewareChange())
            {
                Dictionary <string, IFeature> featuresByName = Store.Features.ToDictionary(x => x.GetName());

                var newFeatureStates = (IDictionary <string, object>)JsonUtil.Deserialize <object>(e.state);
                foreach (KeyValuePair <string, object> newFeatureState in newFeatureStates)
                {
                    // Get the feature with the given name
                    if (!featuresByName.TryGetValue(newFeatureState.Key, out IFeature feature))
                    {
                        continue;
                    }

                    // Get the generic method of JsonUtil.Deserialize<> so we have the correct object type for the state
                    string     deserializeMethodName = nameof(JsonUtil.Deserialize);
                    MethodInfo deserializeMethodInfo = typeof(JsonUtil)
                                                       .GetMethod(deserializeMethodName)
                                                       .GetGenericMethodDefinition()
                                                       .MakeGenericMethod(new Type[] { feature.GetStateType() });

                    // Get the state we were given as a json string
                    string serializedFeatureState = newFeatureState.Value?.ToString();
                    // Deserialize that json using the generic method, so we get an object of the correct type
                    object stronglyTypedFeatureState =
                        string.IsNullOrEmpty(serializedFeatureState)
                                                ? null
                                                : deserializeMethodInfo.Invoke(null, new object[] { serializedFeatureState });

                    // Now set the feature's state to the deserialized object
                    feature.RestoreState(stronglyTypedFeatureState);
                }
            }
            FluxorComponent.AllStateHasChanged();
        }
Пример #2
0
        public async Task DispatchAsync(IAction action)
        {
            if (action == null)
            {
                throw new ArgumentNullException(nameof(action));
            }

            // Do not allow task dispatching inside a middleware-change.
            // These change cycles are for things like "jump to state" in Redux Dev Tools
            // and should be short lived.
            // We avoid dispatching inside a middleware change because we don't want UI events (like component Init)
            // that trigger actions (such as fetching data from a server) to execute
            if (IsInsideMiddlewareChange)
            {
                return;
            }

            if (!HasActivatedStore)
            {
                throw new InvalidOperationException("Store has not been initialized. Add `@Store.Initialize()` to your layout page");
            }

            var actionsToDispatch = new Queue <IAction>();

            actionsToDispatch.Enqueue(action);

            while (actionsToDispatch.Any())
            {
                IAction currentActionToDispatch = actionsToDispatch.Dequeue();

                // Allow middlewares to veto the dispatching of an action
                if (Middlewares.Any(x => !x.MayDispatchAction(currentActionToDispatch)))
                {
                    break;
                }

                ExecuteMiddlewareBeforeDispatch(currentActionToDispatch);

                // Notify all features of this action
                foreach (var featureInstance in FeaturesByName.Values)
                {
                    NotifyFeatureOfDispatch(featureInstance, currentActionToDispatch);
                }
                ;
                FluxorComponent.AllStateHasChanged();

                IEnumerable <IAction> actionsCreatedByMiddlewares =
                    ExecuteMiddlewareAfterDispatch(currentActionToDispatch)
                    ?? new IAction[0];

                // Get any actions generated by side-effects
                IEnumerable <IAction> actionsCreatedBySideEffects =
                    await TriggerEffects(currentActionToDispatch);

                // Now execute any new actions
                IEnumerable <IAction> allNewActionsToDispatch =
                    actionsCreatedByMiddlewares.Union(actionsCreatedBySideEffects);
                foreach (IAction newActionToDispatch in allNewActionsToDispatch)
                {
                    actionsToDispatch.Enqueue(newActionToDispatch);
                }
            }
        }