Dim*_*las 2 javascript ajax jquery knockout.js
我有这个代码:
function MyViewModel()
{
var myviewmodel=this;
myviewmodel.ajaxData=ko.observableArray([]);
myviewmodel.init=function()
{
updateInterval(function()
{
myviewmodel.getData();
},6000);
}
myviewmodel.getData=function()
{
myviewmodel.ajaxData([])
$.get('getData.php')
.done(function(data)
{
if(data.status==='ok' && data.data)
{
$.map(data.data,function(f)
{
var last_item=new AjaxItem(f);
myviewmodel.ajaxData.push(last_item);
})
}
})
}
function AjaxItem(data)
{
var item=this;
item.id=parseInt(data.id);
item.name=ko.observable(data.name);
item.surname=ko.observable(data.surname);
item.viewed=ko.observable(true);
setTimeout(function()
{
item.viewed(false);
},600);
}
}
var vm= new MyViewModel();
ko.applyBindings(vm)
vm.init();
Run Code Online (Sandbox Code Playgroud)
我在这个HTML中查看它
<!doctype html>
<html>
<head>
........
<script src="somejs.js"></script>
<style>
.green{
background-color:green;
}
</style>
</head>
<body>
<table>
<tbody data-bind="foreach:ajaxData">
<tr data-bind="css{'green:viewed'}">
<td data-bind="text:name"></td><td data-bind="text:surname"></td>
</tr>
</tbody>
</table>
</boby>
</html>
Run Code Online (Sandbox Code Playgroud)
问题是,当我进行调用时,我必须重新填充数组ajaxData,并且当我这样做时会出现某种"眨眼",我想要的是找到任何更改的项目并仅显示它们.
有3例不同:
你们的伙伴们有一个想法如何做到这一点.
注意:问题是如何进行比较.我将如何知道返回的值是否存在于已返回的数据中.
您的三个要求正是Knockout Mapping Plugin将为您做的.
但在此之前,您的一般方法有几点需要解决.
首先,让我们从您的viewmodel中获取Ajax内容.如何在一个地方收集所有API调用并将它们作为函数公开?
这暴露.getData()(反过来在.get()内部使用).
var API = {
get: function (url, params) {
return $.get(url, params, null, "json").then(function (result) {
if (result.status === 'ok') return result;
console.error("Error status for " + url + ": " + result.status, result);
}).fail(function (jqXhr, status, error) {
console.error("Could not get " + url + ", error is: " + error);
});
},
getData: function(params) {
return this.get('getData.php', params);
}
};
Run Code Online (Sandbox Code Playgroud)
接下来,不要调用您的viewmodels"Viewmodel".这是他们的目的,不应该是他们的名字.你似乎在这里有两种类型的东西,物品和物品清单.我不知道你的项目实际上都是,所以我坚持的名称Item,你可以选择一个更好的一个.所以让我们做两个构造函数:
function Item(data) {
var self = this;
self.id = parseInt(data.id);
self.name = ko.observable(data.name);
self.surname = ko.observable(data.surname);
self.viewed = ko.observable(true);
setTimeout(function () {
self.viewed(false);
}, 600);
}
function ItemList() {
var self = this;
self.data = ko.observableArray();
self.init = function (data) {
ko.mapping.fromJS(data, ItemList.mapping, self);
};
self.load = function () {
API.getData().done(self.init);
};
}
Run Code Online (Sandbox Code Playgroud)
注意如何API调用gets,使ItemListviewmodel更容易阅读.还要注意如何分离load,并init允许您初始化数据视图模型的你没有通过Ajax获得(localStorage的可能?).
你可以看到我们在ko.mapping.fromJS这里打电话的方式.为了将传入对象映射到正常运行的视图模型,应该像数据属性一样调用viewmodel属性.
假设您的Ajax响应如下所示:
{
status: "ok",
data: [
{id: 1, name: "Doctor", surname: "Evil"},
{id: 2, name: "Austin", surname: "Powers"}
]
}
Run Code Online (Sandbox Code Playgroud)
有两个属性,status和data.
status 我们想忽略,它对于viewmodel的功能并不重要. data包含一个对象列表,这些对象应该成为Item我们的同名可观察数组中的实例.为此,映射插件需要指令.ItemList为方便起见,我们可以将它们打到对象上.
ItemList.mapping = {
ignore: ["status"],
data: {
key: function (data) {
return ko.unwrap(data.id);
},
create: function (options) {
return new Item(options.data);
}
}
};
Run Code Online (Sandbox Code Playgroud)
这告诉映射插件不要打扰status,而是用以下对象做两件事data:
key函数将用于确定对象的ID,因此映射插件知道何时应使用传入对象来更新现有视图模型.我们使用该id属性.create函数将用于将传入的普通对象转换为Item实例.现在每次ko.mapping.fromJS调用来自服务器的新数据时,knockout将挑选现有对象并仅更新已更改的属性,而不是重新绘制整个列表.将从屏幕中删除丢失的对象,将添加新对象.
视图保持不变:
<table>
<tbody data-bind="foreach: data">
<tr data-bind="css: {green: viewed}">
<td data-bind="text: name"></td>
<td data-bind="text: surname"></td>
</tr>
</tbody>
</table>
Run Code Online (Sandbox Code Playgroud)
把它们放在一起(展开并运行示例):
var API = {
get: function (url, params) {
return $.get(url, params, null, "json").then(function (result) {
if (result.status === 'ok') return result;
console.error("Error status for " + url + ": " + result.status);
}).fail(function (jqXhr, status, error) {
console.error("Could not get " + url + ", error is: " + error);
});
},
getData: function(params) {
return this.get('getData.php', params);
}
};
// -------------------------------------------------------------------
function Item(data) {
var self = this;
self.id = parseInt(data.id);
self.name = ko.observable(data.name);
self.surname = ko.observable(data.surname);
self.viewed = ko.observable(true);
setTimeout(function () {
self.viewed(false);
}, 600);
}
function ItemList() {
var self = this;
self.data = ko.observableArray();
self.init = function (data) {
ko.mapping.fromJS(data, ItemList.mapping, self);
};
self.load = function () {
API.getData().done(self.init);
};
}
ItemList.mapping = {
ignore: ["status"],
data: {
key: function (data) {
return ko.unwrap(data.id);
},
create: function (options) {
return new Item(options.data);
}
}
};
// -------------------------------------------------------------------
// Ajax mockup
$.mockjax({
url: "getData.php",
responseText: {
status: "ok",
data: [
{id: 1, name: "Doctor", surname: "Evil"},
{id: 2, name: "Austin", surname: "Powers"}
]
}
});
var vm = new ItemList();
ko.applyBindings(vm);
vm.load();
setInterval(vm.load, 6000);Run Code Online (Sandbox Code Playgroud)
.green {
background-color: green;
}Run Code Online (Sandbox Code Playgroud)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery-mockjax/1.6.2/jquery.mockjax.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.4.0/knockout-min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout.mapping/2.4.1/knockout.mapping.min.js"></script>
<table>
<tbody data-bind="foreach: data">
<tr data-bind="css: {green: viewed}">
<td data-bind="text: name"></td>
<td data-bind="text: surname"></td>
</tr>
</tbody>
</table>
<hr>
<pre data-bind="text: ko.toJSON($root, null, 2)"></pre>Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
140 次 |
| 最近记录: |