Проблема в твоих действиях. Это добавляет задачу с ключом payload
, но вы пытаетесь связать ее с action.task
(которого не существует).
Объект, который будет отправлен в ваш редуктор, будет выглядеть следующим образом:
{
type: 'ADD_TASK',
payload: {
task: 'like it'
}
}
Вы можете ясно видеть здесь, action.task
не существует, но action.payload.task
существует. Либо измените объект вокруг, либо измените его так, чтобы вы могли получить к нему доступ в action.task
:
const addTask = (task) => ({
type: 'ADD_TASK',
task
})
или , измените ваш редуктор:
function tasksReducer(state = initalState, action) {
switch (action.type) {
case 'ADD_TASK':
return {
...state,
tasks: state.tasks.concat([action.payload.task])
};
default:
return state;
}
}
[ 1115] В будущем: небольшая отладка прошла бы долгий путь (и вообще избежал бы этого вопроса). Простой console.log(action)
в верхней части вашего редуктора будет регистрировать вышеупомянутый объект, и вы можете сделать вывод, основываясь на том, почему он пытается добавить неопределенное, почему он не будет работать.
Можно сделать себя чистым подходом XAML путем создания присоединенное поведение .
Что-то вроде этого:
public static class InputBindingsManager
{
public static readonly DependencyProperty UpdatePropertySourceWhenEnterPressedProperty = DependencyProperty.RegisterAttached(
"UpdatePropertySourceWhenEnterPressed", typeof(DependencyProperty), typeof(InputBindingsManager), new PropertyMetadata(null, OnUpdatePropertySourceWhenEnterPressedPropertyChanged));
static InputBindingsManager()
{
}
public static void SetUpdatePropertySourceWhenEnterPressed(DependencyObject dp, DependencyProperty value)
{
dp.SetValue(UpdatePropertySourceWhenEnterPressedProperty, value);
}
public static DependencyProperty GetUpdatePropertySourceWhenEnterPressed(DependencyObject dp)
{
return (DependencyProperty)dp.GetValue(UpdatePropertySourceWhenEnterPressedProperty);
}
private static void OnUpdatePropertySourceWhenEnterPressedPropertyChanged(DependencyObject dp, DependencyPropertyChangedEventArgs e)
{
UIElement element = dp as UIElement;
if (element == null)
{
return;
}
if (e.OldValue != null)
{
element.PreviewKeyDown -= HandlePreviewKeyDown;
}
if (e.NewValue != null)
{
element.PreviewKeyDown += new KeyEventHandler(HandlePreviewKeyDown);
}
}
static void HandlePreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
DoUpdateSource(e.Source);
}
}
static void DoUpdateSource(object source)
{
DependencyProperty property =
GetUpdatePropertySourceWhenEnterPressed(source as DependencyObject);
if (property == null)
{
return;
}
UIElement elt = source as UIElement;
if (elt == null)
{
return;
}
BindingExpression binding = BindingOperations.GetBindingExpression(elt, property);
if (binding != null)
{
binding.UpdateSource();
}
}
}
Затем в Вашем XAML Вы устанавливаете InputBindingsManager.UpdatePropertySourceWhenEnterPressedProperty
свойство к тому, которое Вы хотите обновить, когда Входят клавиша нажата. Как это
<TextBox Name="itemNameTextBox"
Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}"
b:InputBindingsManager.UpdatePropertySourceWhenEnterPressed="TextBox.Text"/>
(Просто необходимо удостовериться, что включали xmlns ссылку пространства имен сброса для "b" в корневом элементе файла XAML, указывающего, который когда-либо пространство имен Вы вставляете InputBindingsManager).
Я не полагаю, что существует любой "чистый XAML" способ сделать то, что Вы описываете. Можно настроить привязку так, чтобы она обновила каждый раз, когда текст в TextBox изменяется (скорее чем, когда TextBox теряет фокус) путем установки свойство UpdateSourceTrigger, как это:
<TextBox Name="itemNameTextBox"
Text="{Binding Path=ItemName, UpdateSourceTrigger=PropertyChanged}" />
, Если Вы устанавливаете UpdateSourceTrigger на "Явный" и затем обработали событие TextBox's PreviewKeyDown (ищущий клавишу Enter) затем, Вы могли достигнуть того, что Вы хотите, но это потребовало бы кода - позади. Возможно, своего рода приложенное свойство (подобный моему свойство EnterKeyTraversal) woudld работает на Вас.
Вы можете легко создать свой собственный элемент управления, унаследованный от TextBox, и повторно использовать его в вашем проекте.
Что-то похожее на это должно сработать:
public class SubmitTextBox : TextBox
{
public SubmitTextBox()
: base()
{
PreviewKeyDown += new KeyEventHandler(SubmitTextBox_PreviewKeyDown);
}
void SubmitTextBox_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter)
{
BindingExpression be = GetBindingExpression(TextBox.TextProperty);
if (be != null)
{
be.UpdateSource();
}
}
}
}
Может быть способ обойти этот шаг , но в противном случае вы должны выполнить привязку следующим образом (используя Explicit):
<custom:SubmitTextBox
Text="{Binding Path=BoundProperty, UpdateSourceTrigger=Explicit}" />