2

条件付きレンダリングに問題があります。これが私の100%の作業ビューです:

function todoItem(todo) {
  return li('.list-item',[
    todo.editing ? input('.todo-edit', {type: 'text', value: todo.text, autofocus: true, attributes: { 'data-id': todo.id }}) : '',
    !todo.editing ? span(`.todo ${todo.completed ? '.completed' : ''}`, { attributes: { 'data-id': todo.id }}, todo.text) : '',
    button('.remove-todo', {type: 'button', value: todo.id}, 'remove'),
    todo.completed ? button('.unmark-todo', {type: 'button', value: todo.id}, 'unmark') : '',
    !todo.completed ? button('.mark-todo', {type: 'button', value: todo.id}, 'mark as done') : ''
  ]);

const view = (state$) => {
  return state$.map(todos =>
    div([
      input('.todo-input', {type: 'text', placeholder: 'Todo', value: ''}),
      ul(todos.items.map(todo => todoItem(todo))),
      footer(todos)
    ])
  );
};

問題は、条件付きボタンを 2 つの個別の条件ではなく if-else に変更しようとしたときです。

todo.completed ?
  button('.unmark-todo', {type: 'button', value: todo.id}, 'unmark') : 
  button('.mark-todo', {type: 'button', value: todo.id}, 'mark as done')

ボタンを「マーク解除」に切り替えてから、再び「マーク」に戻すようです(コンソールログで確認しました)。私のインテントは.mark.unmarkの 2 つのクラスにマップされているので、それは問題ではないと思います...

それは実際のエラーですか、それとも何か不足していますか?

4

1 に答える 1

2

dom ドライバーでこのバグが発生しています: https://github.com/cyclejs/core/issues/228

「問題」は、トグルしている両方の要素がボタンであることです。todo.completedそのため、!todo.completedvirtual-domに切り替えると、新しいボタンは作成されず、古いボタンのクラスとラベルが更新されるだけです (DOM の変更を最小限に抑えるため)。

これは、クリック イベントがまだ処理されている間に同期的に発生します。クラス名が更新されると、イベントは次のリスナーによって処理されます。このリスナーは、(新しい) クラス名と一致し、イベントも受け入れます。この 2 番目のリスナーは、タスクのマークを再度解除するリスナーです。

簡単な解決策は、両方のボタンにkey属性を与えて、virtual-dom にボタンを強制的に再作成させることです。しかし、私が言ったように、これは dom ドライバーのバグです。

todo.completed ?
  button('.unmark-todo', {key: 'unmark', type: 'button', value: todo.id}, 'unmark') : 
  button('.mark-todo', {key: 'mark', type: 'button', value: todo.id}, 'mark as done')
于 2016-05-09T10:02:22.997 に答える