- HTML5 Web Application Development By Example Beginner's Guide
- J.M. Gustafson
- 862字
- 2021-08-13 16:50:27
Time for action – implementing the bindings
Let's head back over to the task template in our HTML file and add some custom data attributes. We'll add custom attributes to all of the task details <input>
and <select>
elements. The data attribute name will be data-field
, and the attribute value will be the name of the field the element matches to in the Task
object. We will use those attributes later in our JavaScript to hook the DOM elements and data model together:
<div class="details"> <label>Start date:</label> <input type="date" data-field="startDate"/><br/> <label>Due date:</label> <input type="date" data-field="dueDate"/><br/> <label>Status:</label> <select data-field="status"> <!— options removed... --> </select><br/> <label>Priority:</label> <select data-field="priority"> <!— options removed... --> </select><br/> <label>% Complete:</label> <input type="number" data-field="pctComplete" min="0" max="100" step="10" value="0"/> </div>
Now that we have a data model, we need to go into the TaskAtHandApp
object in taskAtHand.js
and update it to use that model. First we'll add a taskList
variable and initialize it to an instance of a TaskList
object:
function TaskAtHandApp()
{
var version = "v3.2",
appStorage = new AppStorage("taskAtHand"),
taskList = new TaskList();
Then we'll go into the addTask()
method and add code to create a new Task
object, and add it to the task list. This is also where we save the nextTaskId
value into localStorage
after it's been incremented:
function addTask() { var taskName = $("#new-task-name").val(); if (taskName) { var task = new Task(taskName); taskList.addTask(task); appStorage.setValue("nextTaskId", Task.nextTaskId); addTaskElement(task); saveTaskList(); // Reset the field $("#new-task-name").val("").focus(); } }
Notice that we also changed the parameter of the addTaskElement()
method to pass in the Task
object. So let's update the addTaskElement()
method to take a Task
object as the parameter instead of a task name:
function addTaskElement(task) { var $task = $("#task-template .task").clone(); $task.data("task-id", task.id); $("span.task-name", $task).text(task.name);
After creating a new task element in the DOM we set the task ID on it using a custom data attribute named task-id
. This is done with the jQuery data()
method that takes the data attribute name and value as parameters. Next we set the task name into the <span>
attribute from the task.name
field.
Now we will implement the first part of the data binding. This next block of code uses the data attributes we previously added to the markup to set the values from the Task
object into the associated <input>
and <select>
elements in the details section:
// Populate all of the details fields
$(".details input, .details select", $task).each(function() {
var $input = $(this);
var fieldName = $input.data("field");
$input.val(task[fieldName]);
});
Here's how it works:
- First it finds all
<input>
and<select>
elements inside the task element. - Then it calls the jQuery
each()
method, which is used to iterate over the set of selected elements, passing in acallback
function. - Inside the
callback
functionthis
points to the current element. So first we wrap the element in a jQuery object. - Then we use the
data()
method to get the value of thedata-field
custom attribute, which is the name of the field in theTask
object associated with the element. - Finally we set the value of the user control to the value of the field in the
Task
object. We get the value from theTask
object using square brackets. Remember that in JavaScriptobject["field"]
is the .same asobject.field
.Note
You can think of using square brackets to access object fields as similar to using reflection in C# or Java to dynamically access values in objects at runtime.
Now we need to add code to go the other way. Whenever the user changes the value of a form control we want to automatically save it back to the data model. So let's add a change event handler for each of the details form controls:
$(".details input, .details select", $task).change(function() { onChangeTaskDetails(task.id, $(this)); });
This calls the onChangeTaskDetails()
method, passing in the task ID and the form control element that changed wrapped in a jQuery object. Let's implement that method:
function onChangeTaskDetails(taskId, $input) { var task = taskList.getTask(taskId) if (task) { var fieldName = $input.data("field"); task[fieldName] = $input.val(); saveTaskList(); } }
Let's break it down to see how it works:
- First it gets the
Task
object from the task list with the specified ID. - After making sure we got an object back (you never know, so always check) we get the
Task
object field name from the element'sdata-field
attribute. - Then we set the value of the field on the
Task
object to the value of the form control element, again using square brackets to access it dynamically. - Finally we call
saveTaskList()
to commit the change tolocalStorage
.
That reminds me, we need to rewrite the saveTaskList()
method to save our new TaskList
object. That's easy enough. We just call the getTasks()
method of the task list to get the array of Task
objects. Then we save the array to localStorage
:
function saveTaskList() { appStorage.setValue("taskList", taskList.getTasks()); }
Note
If you have old task list data from the previous examples you will need to delete it before using the new data model. In Chrome developer tools you can click on the item and press the Delete key to remove it.
What just happened?
First we created a data model to hold all of the task data. Then we added data binding to our application using custom data attributes to automatically update the data model when a field on the page changes. Then we saved the task list to local storage.
- Clojure Programming Cookbook
- C++ Builder 6.0下OpenGL編程技術
- Magento 2 Theme Design(Second Edition)
- Access 2016數據庫管
- 概率成形編碼調制技術理論及應用
- C程序設計案例教程
- C++新經典
- Cybersecurity Attacks:Red Team Strategies
- 學習OpenCV 4:基于Python的算法實戰
- 零基礎學Kotlin之Android項目開發實戰
- Unity 2018 Augmented Reality Projects
- Swift語言實戰晉級
- H5+移動營銷設計寶典
- Node.js實戰:分布式系統中的后端服務開發
- Backbone.js Patterns and Best Practices