2015-08-09 2 views
3

Простой Todo-App. Пожалуйста, извините мое невежество, чтобы задать довольно простой вопрос.VueJs: Как отредактировать массив Item

Но как бы вы шли и редактировали определенный элемент массива?

Как правило, я пытаюсь привязать значение моего ввода к новому свойству объекта данных, а затем присвоить это новое свойство старому свойству при двухстороннем привязке данных к клику.

Как это: http://jsfiddle.net/z7960up7/

Ну в моем случае я использую V-повторить директиву, которая закругляется через мой массив данных, но я не могу использовать директиву v-модель использовать двухстороннюю привязку данных, поскольку значения свойств будут повреждены, если я это сделаю. (Смотрите здесь: http://jsfiddle.net/doL46etq/2/)

А теперь мне интересно, как я бы об обновлении моего массива задач:

Моей идея заключается в том, чтобы передать VueObject (это) с помощью моего метода на щелчке, а затем определить индекс на мой обработчик событий, а затем обновить массив задач, с использованием индекса, например:

HTML:

<input v-el="editInputField" type="text" value="{{ task.body }}" v-on="keyup: doneEdit(this) | key 'enter'"/> 

<button v-on="click: editTask(this)"> 
    Edit 
</button> 

JS:

methods: { 
    editTask: function (task) { 
     var taskIndex = this.tasks.indexOf(task.task); 

     this.tasks[taskIndex] = { 
      'body': document.querySelector('input').value, 
      'completed': false 
     }; 

     console.log(task.task.body); 
    }, 
} 

Вот моя скрипка об этом:

http://jsfiddle.net/doL46etq/3/

Но объект данных не обновляется на всех, и мне интересно, как я бы об этом и обновить его.

Каков наилучший способ редактирования элемента в массиве с помощью Vue?

Редактировать: простой способ: просто удалить элемент и добавить новое в массив с помощью метода push, но я действительно хочу просто обновить элемент, потому что мне нравится синхронизировать файл данных с моим бэкэндом.

ответ

2

На самом деле самый простой способ обновить массив item, является двусторонним связывать корпус задачи с директивой v-model.

Пример:

http://jsfiddle.net/z7960up7/2/

<div id="demo"> 
    {{ message }} 

    <div class="edit"> 
     <input type="text" v-model="message">   
     <button v-on="click: editMessage">Edit</button> 
    </div>   
    <pre>{{ $data | json }}</pre> 
</div> 

И огнь события, когда вы размыть из поля ввода или кнопка редактирования удара.

Также скрыть поле ввода с помощью css, используя директиву v-class.

2

Короткий ответ: используйте компонент в расширенном конструкторе, затем передайте индекс этому компоненту в качестве свойства HTML и используйте рассчитанные свойства для связи взад и вперед по вашим данным.

Но не удовлетворены только коротким ответом. Вот длинный:

Ситуация: Я использую ваш JSFiddle в качестве основы для этого ответа.

в HTML у вас есть:

<td>{{ task.body }}</td> 
       <td> 
        <div> 
         <input v-el="editInputField" type="text" value="{{ task.body }}" v-on="keyup: doneEdit(this) | key 'enter'" v-model="newEdit"/> 
        </div> 
       </td> 
       <td> 
        <button v-on="click: editTask(this)" class="mdl-button mdl-js-button mdl-button--icon"> <i class="material-icons">create</i> 

        </button> 
       </td> 

Мы хотим заменить этот код с компонентом. Использование этого компонента позволяет нам определить индекс/строку, над которой мы работаем в вашем наборе данных.

<td v-component="listitem" index="{{$index}}"></td> 

Следующий шаг: определение компонента.

Чтобы не облачить наш экземпляр компонентом, мы создадим отдельный конструктор для объекта vue, чтобы мы могли назначить новый элемент нашему новому объекту.

Это делается с использованием удлинения.

window.newVue = Vue.extend({ 
components: 
{ 
    'listitem': { 

     props: ['index'], 

     computed: { 
     // both get and set 
     body: { 
      get: function() { 

      return this.$parent.tasks[this.index].body; 
      }, 
      set: function (v) { 
      this.$parent.tasks[this.index].body = v 
      } 
     } 
     }, 
     template: '<td>{{ body }}</td><td><div><input type="text" v-model="body" value="{{ body }}"/></div></td><td></td>', 
    } 
} 

});

Поскольку мы не можем правильно определить наши данные с использованием расширения, мы просто предположим, что данные уже существуют при написании компонента.

Шаг 3: определение фактических данных: Вместо использования Vue в качестве нашего конструктора объектов мы теперь используем наш недавно созданный экземпляр.

new newVue({ 
el: '#todoapp', 

data: { 
    tasks: [{ 
     'body': 'Eat breakfast', 
     'completed': false 
    }, { 
     'body': 'Drink milk', 
     'completed': false 
    }, { 
     'body': 'Go to the store', 
     'completed': false 
    }], 

    newTask: '', 
}, 

});

Вот и все!

В случае, если Вы не могли бы следовать тому, что случилось: Вот Fiddle!

PS: Более подробная информации о рабочем этой коде можно найти на vuejs.org

+0

Спасибо Sangun. Хотя мне понадобится некоторое время, чтобы проработать ваш ответ, поскольку я еще не развязал компоненты vue. Хотя мне было интересно, если бы вы могли объяснить, как здесь было сделано редактирование/обновление, я думаю, без использования компонентов: https://github.com/tastejs/todomvc/blob/gh-pages/examples/vue/ js/app.js – LoveAndHappiness

+0

Также, когда пришло время запустить Ajax-запрос в вашем jsfiddle? – LoveAndHappiness

+1

Это зависит от того, что вы хотите сделать с помощью запроса Ajax. Если вы хотите обновить информацию в базе данных, то лучшим вариантом будет стрельба из Setter на компоненте (однако имейте в виду, что запрос будет производиться всякий раз, когда меняется один символ, поэтому вы можете захотеть выставить задержку и буфера всех изменений!) Если в случае, если вы хотите обновить данные, я бы предложил добавить новое свойство, а не определять данные. Это позволит вам редактировать значение через свойство. Это означает, что если вы будете использовать элемент v-repeat, вы можете использовать {{item.property}} для обновления переменной. – Sangun