2016-10-06 4 views
0

using knockoutjs Я хочу иметь формы, которые допускают бесконечный выбор, но мне нужна форма для отображения, чтобы пользователь знал, что она существует. Я в порядке, начиная с 3-х форм, поэтому я хотел бы инициализировать пустые объекты при отображении страницы. По какой-то причине, когда я инициализировать один объект он ломает мой код:инициализация пустой страницы разрывов; knockoutJS

 function Task(data) { 
 
      this.title=ko.observable(data.title); 
 
      this.isDone=ko.observable(data.isDone); 
 
     } 
 

 
     function TaskListViewModel() { 
 
      // Data 
 
      var self=this; 
 
      self.tasks=ko.observableArray([]); 
 
      // self.tasks.push({'title': ''}) 
 
      self.newTaskText=ko.observable(); 
 
      self.incompleteTasks=ko.computed(function() { 
 
       return ko.utils.arrayFilter(self.tasks(), function(task) { 
 
        return !task.isDone() 
 
       }); 
 
      }); 
 

 
      // Operations 
 
      self.addTask=function() { 
 
       self.tasks.push(new Task({ 
 
        title: this.newTaskText() 
 
       })); 
 
       self.newTaskText(""); 
 
      }; 
 

 
      self.removeTask=function(task) { 
 
       self.tasks.destroy(task) 
 
      }; 
 

 
      self.incompleteTasks=ko.computed(function() { 
 
       return ko.utils.arrayFilter(self.tasks(), 
 
        function(task) { 
 
         return !task.isDone() && !task._destroy 
 
        }); 
 
      }); 
 

 
      self.save=function() { 
 
       $.ajax(".", { 
 
        data: ko.toJSON({ 
 
         tasks: self.tasks 
 
        }), 
 
        type: "post", 
 
        contentType: "application/json", 
 
        success: function(result) { 
 
         alert(result) 
 
        } 
 
       }); 
 
      }; 
 

 
      // load initial state from server, convert to tasks, then add em to self.tasks 
 
      $.getJSON(".", function(allData) { 
 
       var mappedTasks=$.map(allData, function(item) { 
 
        return new Task(item) 
 
       }); 
 
       self.tasks(mappedTasks); 
 
      }); 
 
      
 
      self.tasks.push({'title': ''}) 
 
     } 
 
     ko.applyBindings(new TaskListViewModel());
body { font-family: Helvetica, Arial } 
 
    input:not([type]), input[type=text], input[type=password], select { background-color: #FFFFCC; border: 1px solid gray; padding: 2px; } 
 

 
    .codeRunner ul {list-style-type: none; margin: 1em 0; background-color: #cde; padding: 1em; border-radius: 0.5em;} 
 
    .codeRunner ul li a { color: Gray; font-size: 90%; text-decoration: none } 
 
    .codeRunner ul li a:hover { text-decoration: underline } 
 
    .codeRunner input:not([type]), input[type=text] { width: 30em; } 
 
    .codeRunner input[disabled] { text-decoration: line-through; border-color: Silver; background-color: Silver; } 
 
    .codeRunner textarea { width: 30em; height: 6em; } 
 
    .codeRunner form { margin-top: 1em; margin-bottom: 1em; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<body class="codeRunner"> 
 
    <h3> Stuff </h3> 
 
    
 
     <div data-bind="foreach: tasks, visible: tasks().length > 0"> 
 
      <p data-bind="value: title"></p> 
 
     </div> 
 
      
 
     <ul data-bind="foreach: tasks, visible: tasks().length > 0"> 
 
      <li> 
 
       <input data-bind="value: title, disable: isDone" /> 
 
       <a href="#" data-bind="click: $parent.removeTask">Delete</a> 
 
      </li> 
 
     </ul> 
 
      You have <b data-bind="text: incompleteTasks().length">&nbsp;</b> incomplete task(s) 
 
      <span data-bind="visible: incompleteTasks().length == 0"> -it 's beer time!</span> 
 
       
 
     <form data-bind="submit: addTask"><button type="submit">Add</button></form> 
 

 
    <script> 
 

 
    </script> 
 

 
</body>

Что такое шаблон в нокауте, чтобы безопасно инициализировать с этим блоком JS? Спасибо

+0

Ваша проблема линия 'self.tasks.push ({ 'название': ''})': вы не толкая объект задачи на список, вы нажимаете необработанные данные. 'self.tasks.push (новая задача ({title:" "}))' вероятно, что вы там хотите. – Retsam

ответ

1

Причина, по которой вы получаете сообщение об ошибке, заключается в том, что свойство isDone в вашей начальной задаче не было установлено. У вас также есть Task viewModel, так почему бы не использовать его для инициализации массива? Я только что использовал выражение IIFE (), вызывающее функцию), чтобы инициализировать новые задачи, добавив Task в цикл for. Вы можете сделать это вручную или в зависимости от того, какой вы предпочитаете.

Также обратите внимание на использование вами ключевого слова this. См. self.addTask в вашем коде.

Я не уверен, что это именно то, что вы ищете, но я предполагаю, что вам понадобится ввод текста для ввода newTaskText или я что-то упускаю? Во всяком случае, это похоже на работу. Надежда отвечает на ваш вопрос.

function Task(data) { 
 
    this.title = ko.observable(data.title); 
 
    this.isDone = ko.observable(data.isDone || false); 
 
} 
 

 
function TaskListViewModel() { 
 
    // Data 
 
    var self = this; 
 
    self.tasks = ko.observableArray([]); 
 
    // self.tasks.push({'title': ''}) 
 
    self.newTaskText = ko.observable(); 
 
    self.incompleteTasks = ko.computed(function() { 
 
    return ko.utils.arrayFilter(self.tasks(), function(task) { 
 
     return !task.isDone() 
 
    }); 
 
    }); 
 

 
    // Operations 
 
    self.addTask = function() { 
 
    self.tasks.push(new Task({ 
 
     title: self.newTaskText(), 
 
     isDone: false 
 
    })); 
 
    self.newTaskText(""); 
 
    }; 
 

 
    self.removeTask = function(task) { 
 
    self.tasks.destroy(task) 
 
    }; 
 

 
    self.incompleteTasks = ko.computed(function() { 
 
    return ko.utils.arrayFilter(self.tasks(), 
 
     function(task) { 
 
     return !task.isDone() && !task._destroy 
 
     }); 
 
    }); 
 

 
    (function(numTasks) { 
 
    for (var x = 0; x < numTasks; x++) { 
 
     self.tasks.push(new Task({ 
 
     title: "" 
 
     })); 
 
    } 
 
    })(3) 
 

 
} 
 
ko.applyBindings(new TaskListViewModel());
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script> 
 
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script> 
 

 
<body class="codeRunner"> 
 
    <h3> Stuff </h3> 
 

 
    <input data-bind="textInput: newTaskText" type="text" /> 
 
    <input data-bind="click: addTask" type="button" value="Add Task" /> 
 

 
    <div data-bind="foreach: tasks, visible: tasks().length > 0"> 
 
    <p data-bind="value: title"></p> 
 
    </div> 
 

 
    <ul data-bind="foreach: tasks, visible: tasks().length > 0"> 
 
    <li> 
 
     <input data-bind="value: title, disable: isDone" /> 
 
     <a href="#" data-bind="click: $parent.removeTask">Delete</a> 
 
    </li> 
 
    </ul> 
 
    You have <b data-bind="text: incompleteTasks().length">&nbsp;</b> incomplete task(s) 
 
    <span data-bind="visible: incompleteTasks().length == 0"> -it 's beer time!</span> 
 

 

 

 
    <script> 
 
    </script> 
 

 
</body>

+0

Отлично, работает как шарм. Спасибо, Стюарт – codyc4321

Смежные вопросы