使用knockout,我想调用Ajax方法并异步更新我的HTML。
我的方法:“GetPopularChannelResult”
我能够恢复json并将其绑定到模型,但无法更新我的视图。
我必须首先创建一个空模型,“频道”,否则在页面加载时,淘汰会说我没有记录。
修改 我正在使用ko.mapping或ko.mapper(测试目的),我仍然遇到麻烦。
https://github.com/LucasLorentz/knockout.mapper https://github.com/SteveSanderson/knockout.mapping
我想我正在迭代一个对象的属性,但我不确定: How to use knockout to iterate over an object (not array)
我可能没有正确构建我的频道模型,我确实注意到它的一些问题,请进一步了解详细信息。
JSON返回 http://jsonblob.com/52f11ec5e4b00cc4750d0dc2
看看上面的json blob,我注意到我有一个24个属性的对象。这可能是我没有看到任何数据的原因吗?
HTML(查看)
<div class="row">
<div class="col-md-9">
<img src="~/Content/Images/ajax-loader.gif" id="spinner" class="ajax-loader" alt="ajax loader" />
@* TODO: link to a video page *@
<section id="channelResult" class="hide" data-bind="foreach: channel.data.records">
<p data-bind="text: username"></p>
<video width="400" height="400" controls>
<source data-bind="attr: { src: videoUrl }" type="video/mp4" />
</video>
<p data-bind="text: description"></p>
</section>
</div>
</div>
JS
$(function() {
var channelIdFromUrl = $.url().param('channelId');
var pageFromUrl = $.url().param('page');
// The ViewModel
my.vm = function () {
var channel = {
code: ko.observable('waiting for data'),
data: [
{
count: ko.observable(0),
records: [
{
liked: ko.observable('0'),
foursquareVenueId: ko.observable(null),
userId: ko.observable(0),
private: ko.observable(0),
likes: ko.observableArray([{}]),
thumbnailUrl: ko.observable('waiting for data'),
explicitContent: ko.observable(0),
vanityUrls: ko.observableArray([{}]),
verified: ko.observable(1),
avatarUrl: ko.observable('waiting for data'),
comments: ko.observableArray([{}]),
entities: ko.observableArray([{}]),
videoLowURL: ko.observable('waiting for data'),
permalinkUrl: ko.observable('waiting for data'),
username: ko.observable('waiting for data'),
description: ko.observable('waiting for data'),
tags: ko.observableArray([{}]),
postId: ko.observable(0),
videoUrl: ko.observable('waiting for data'),
created: ko.observable('waiting for data'),
shareUrl: ko.observable('waiting for data'),
myRepostId: ko.observable(0),
promoted: ko.observable(0),
reposts: ko.observableArray([{}])
}
],
nextPage: ko.observable('0'),
size: ko.observable('0'),
anchorStr: ko.observable('waiting for data'),
previousPage: ko.observable(null),
anchor: ko.observable('waiting for data')
}
],
success: ko.observable('waiting for data'),
error: ko.observable('waiting for data')
},
getRecords = function () {
// It returns undefined first round, until json returns...
return my.vm.channel.data.records;
},
channelData = {
ChannelId: ko.observable(channelIdFromUrl),
Page: ko.observable(pageFromUrl)
},
// TODO: work on this toggle later
//isPopular = ko.observable(true),
//toggleChannelButton = function() {
// if (this.IsPopular()) {
// this.IsPopular(false);
// self.btnText('Get Popular');
// } else {
// this.IsPopular(true);
// self.btnText('Get Recent');
// }
//},
//btnText = ko.observable('Get Recent'),
loadChannelPopularCallback = function (json) {
var parsedJson = $.parseJSON(json);
ko.mapper.fromJS(parsedJson, {}, my.vm.channel);
},
loadPopularChannel = function() {
my.VineDataService.getVineItems(my.vm.loadChannelPopularCallback, channelData, "GetPopularChannelResult");
};
return {
channel: channel,
channelData: channelData,
loadChannelPopularCallback: loadChannelPopularCallback,
getRecords: getRecords,
loadPopularChannel: loadPopularChannel
//IsPopular: isPopular,
//toggleChannelButton: toggleChannelButton,
//btnText: btnText
};
}();
my.vm.loadPopularChannel();
ko.applyBindings(my.vm);
JS dataservice.js
// Depends on scripts:
// ajaxservice.js
(function (my) {
"use strict";
my.VineDataService = {
getVineItems : function (callback, channelData, method) {
my.ajaxService.ajaxGetJson(method, channelData, callback);
}
};
}(my));
ajax服务
// ajaxService
// Depends on scripts:
// jQuery
(function (my) {
var serviceBase = '/Home/',
getSvcUrl = function (method) { return serviceBase + method; };
my.ajaxService = (function () {
var ajaxGetJson = function (method, jsonIn, callback) {
$.ajax({
url: getSvcUrl(method),
type: 'GET',
data: ko.toJS(jsonIn),
dataType: 'JSON',
contentType: 'application/json; charset=utf-8',
success: function (json) {
callback(json);
}
});
},
ajaxPostJson = function (method, jsonIn, callback) {
$.ajax({
url: getSvcUrl(method),
type: "POST",
data: ko.toJSON(jsonIn),
dataType: "json",
contentType: "application/json; charset=utf-8",
success: function (json) {
callback(json);
}
});
};
return {
ajaxGetJson: ajaxGetJson,
ajaxPostJson: ajaxPostJson
};
})();
}(my));
我的命名空间
var my = my || {}; //my namespace
通知 在我更新数据之前,我有0:对象 后记,我仍然在我的模型中有这个,我有一个新的记录:Object [0],这很奇怪,因为我认为它会更新旧数据。
在映射之前从console.log输出
code: function observable() {
data: Array[1]
0: Object
anchor: function observable() {
anchorStr: function observable() {
count: function observable() {
nextPage: function observable() {
previousPage: function observable() {
records: Object[0]
__ko_proto__: function (initialValue) {
_latestValue: Array[1]
0: Object
length: 1
__proto__: Array[0]
_subscriptions: Object
arguments: null
cacheDiffForKnownOperation: function (rawArray, operationName, args) {
caller: null
destroy: function (valueOrPredicate) {
destroyAll: function (arrayOfValues) {
equalityComparer: function valuesArePrimitiveAndEqual(a, b) {
extend: function applyExtenders(requestedExtenders) {
getSubscriptionsCount: function () {
hasSubscriptionsForEvent: function (event) {
indexOf: function (item) {
length: 0
name: "observable"
notifySubscribers: function (valueToNotify, event) {
peek: function () { return _latestValue }
pop: function () {
prototype: observable
push: function () {
remove: function (valueOrPredicate) {
removeAll: function (arrayOfValues) {
replace: function (oldItem, newItem) {
reverse: function () {
shift: function () {
slice: function () {
sort: function () {
splice: function () {
subscribe: function (callback, callbackTarget, event) {
unshift: function () {
valueHasMutated: function () { observable["notifySubscribers"](_latestValue); }
valueWillMutate: function () { observable["notifySubscribers"](_latestValue, "beforeChange"); }
__proto__: function Empty() {}
<function scope>
size: function observable() {
__proto__: Object
length: 1
__proto__: Array[0]
error: function observable() {
success: function observable() {
__proto__: Object
映射后从console.log输出
__ko_mapping__: Object
code: function observable() {
data: Array[1]
0: Object
anchor: function observable() {
anchorStr: function observable() {
count: function observable() {
length: 1
nextPage: function observable() {
previousPage: function observable() {
records: Object[0]
__ko_proto__: function (initialValue) {
_latestValue: Array[20]
0: Object
avatarUrl: function observable() {
comments: Object
created: function observable() {
description: function observable() {
entities: Object[0]
explicitContent: function observable() {
foursquareVenueId: function observable() {
liked: function observable() {
likes: Object
myRepostId: function observable() {
permalinkUrl: function observable() {
postId: function observable() {
private: function observable() {
promoted: function observable() {
reposts: Object
shareUrl: function observable() {
tags: Object[0]
thumbnailUrl: function observable() {
userId: function observable() {
username: function observable() {
vanityUrls: Object[0]
verified: function observable() {
videoLowURL: function observable() {
videoUrl: function observable() {
__proto__: Object
1: Object
2: Object
3: Object
4: Object
5: Object
6: Object
7: Object
8: Object
9: Object
10: Object
11: Object
12: Object
13: Object
14: Object
15: Object
16: Object
17: Object
18: Object
19: Object
length: 20
__proto__: Array[0]
_subscriptions: Object
arguments: null
cacheDiffForKnownOperation: function (rawArray, operationName, args) {
caller: null
destroy: function (valueOrPredicate) {
destroyAll: function (arrayOfValues) {
equalityComparer: function valuesArePrimitiveAndEqual(a, b) {
extend: function applyExtenders(requestedExtenders) {
getSubscriptionsCount: function () {
hasSubscriptionsForEvent: function (event) {
indexOf: function (item) {
length: 0
mappedCreate: function (a){if(-1!==b.mappedIndexOf(a))throw Error("There already is an object with the key that you specified.");var c=h()?x(a):a;u()&&(a=v(c,a),e.isWriteableObservable(c)?c(a):c=a);b.push(c);return c}
mappedDestroy: function (a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.destroy(function(a){return c(m(a))})}
mappedDestroyAll: function (a){var c=C(a,m);return b.destroy(function(a){return-1!=
mappedGet: function (a){return b()[b.mappedIndexOf(a)]}
mappedIndexOf: function (a){var c=C(b(),m);a=m(a);return e.utils.arrayIndexOf(c,a)}
mappedRemove: function (a){var c="function"==typeof a?a:function(b){return b===m(a)};return b.remove(function(a){return c(m(a))})}
mappedRemoveAll: function (a){var c=C(a,m);return b.remove(function(a){return-1!=e.utils.arrayIndexOf(c,m(a))})}
name: "observable"
notifySubscribers: function (valueToNotify, event) {
peek: function () { return _latestValue }
pop: function () {
prototype: observable
push: function () {
remove: function (valueOrPredicate) {
removeAll: function (arrayOfValues) {
replace: function (oldItem, newItem) {
reverse: function () {
shift: function () {
slice: function () {
sort: function () {
splice: function () {
subscribe: function (callback, callbackTarget, event) {
unshift: function () {
valueHasMutated: function () { observable["notifySubscribers"](_latestValue); }
valueWillMutate: function () { observable["notifySubscribers"](_latestValue, "beforeChange"); }
__proto__: function Empty() {}
<function scope>
size: function observable() {
__proto__: Array[0]
error: function observable() {
success: function observable() {
__proto__: Object
答案 0 :(得分:0)
我想出了问题,我映射的模型不正确。
我正密切关注json并与映射的json进行比较,我注意到它中有一个额外的对象。这导致我清理了我的频道映射。
内部 my.vm = function(){我注意到数据是一个对象,所以它不需要这些人“[]”。然后我注意到了
var channel = {
data: {
records: [
{
username: ko.observable(),
description: ko.observable(),
videoUrl: ko.observable()
}
],
},
},
然后我注意到我的数据根本没有刷新,所以我在回调方法中移动了我的绑定。这是一个临时修复,我不明白为什么数据不只是刷新?
如果有人知道为什么会这样,我真的很想知道。
loadChannelPopularCallback = function(json) {
ko.mapping.fromJSON(json, {}, my.vm.channel);
ko.applyBindings(my.vm);
},