gpt4 book ai didi

javascript - BackboneJS - 监听嵌套模型的变化

转载 作者:行者123 更新时间:2023-11-28 09:43:13 25 4
gpt4 key购买 nike

简短版本:我有一个 Backbone 模型,其属性之一是第二个 Backbone 模型。第一个模型中的函数更改了第二个模型的状态,但我的 View (正在监听第一个模型的更改)似乎并未获取第二个模型的状态,尽管有大量日志记录表明并非如此(我一直在不同点记录 this 以确认范围等)。我该如何解决这个问题?

长版本:我有一个代表学术类(class)的 Backbone 模型 Course 和一个代表列表的模型 NameList注册类(class)的学生人数。一个类(class)“有一个”NameListNameList 由服务器上的单个文本文件支持。

我希望在 Course 模型中有一个名为 importNameList 的函数,它创建一个新的 NameList 模型并导致 NameList 模型并从后端获取其数据。根据我的观点,CourseView正在监听Course模型的更改,并且Course模型有一个NameList ,看来这应该相应地更新 View 。我的问题是事实并非如此。

我想做什么

var course = new Course();
var courseView = new CourseView({model : course});
courseView.model.importNameList('students.txt'); // Will cause view to re-render

我必须做什么

var course = new Course(); // same 
var courseView = new CourseView({model : course}); // same
courseView.model.importNameList('students.txt'); // same
courseView.render(); // Argh, manually calling this is ugly.

这是我的带有日志记录语句的代码。这些模型扩展了 Backbone.DeepModel 只是因为我认为它可以解决我的问题,但事实并非如此。

控制台输出

[console] var course = new Course();
[console] var courseView = new CourseView({model : course});
[console] course.importNameList('students.txt');

Course >>> importNameList
NameList >>> initialize()
NameList >>> fetch()
GET http://localhost/files/students.txt 200 OK 16ms
CourseView >>> render() // Render starts before fetch completes
CourseView <<< render() // Render finishes before fetch completes
Course <<< importNameList
NameList <<< fetch()

[console] courseView.render();

CourseView >>> render()
alice
bob
charlie
dan
erica
fred
george
CourseView <<< render()

Course.js

var Course = Backbone.DeepModel.extend({

defaults : {
nameList : new NameList()
},

initialize: function(options) {

if (options && options.nameList) {
this.set({nameList : options.nameList});
}

},

importNameList : function(fileName) {

console.log("Course >>> importNameList");
var nameList = new NameList({fileName : fileName});
this.set({nameList : nameList});
console.log("Course <<< importNameList");
}
});

NameList.js

var NameList = Backbone.DeepModel.extend({

defaults : {
fileName : 'new.txt',
names : []
},

initialize: function(options) {

console.log("NameList >>> initialize()");
var model = this;

if (options && options.fileName) {
model.set({fileName : options.fileName});
}
model.fetch();
},

fetch : function() {
console.log("NameList >>> fetch()");
var model = this;
$.ajax({
url : '/files/' + model.get('fileName'),
success : function(response) {
model.set({names : response.split('\n')});
console.log("NameList <<< fetch()");
}
});
}
});

CourseView.js

var CourseView = Backbone.View.extend({

initialize : function(options) {

var view = this;
if (options && options.model) {
view.model = options.model;
} else {
view.model = new Course();
}

view.model.on('change', function() {
view.render();
});

},

render : function() {

console.log("CourseView >>> render()");
var names = this.model.get('nameList').get('names');
for (var i = 0; i < names.length; i++) {
console.log(names[i]);
}
console.log("CourseView <<< render()");
return this;
}

});

最佳答案

快速的答案是使用 jQuery a deferred目的。您可以在this article中找到有关将延迟与backbone.js一起使用的更多信息。 .

我会添加更多具体信息,但我不太清楚为什么要覆盖 fetch,这似乎是灾难的根源。我会坚持使用backbone的原始获取方法,并将其保留在NameList的初始值设定项之外,从Course.js调用它,并使用从它返回的延迟来保证一旦获取完成就运行后面的步骤。

更新:

以下是实现此目的的一种方法的草图。首先从 NameListinitialize 方法中取出 model.fetch(); 行,并在 importNameList 中调用它code>,使用其返回值(延迟对象)作为 importNameList 的返回值:

var nameList = new NameList({fileName : fileName});
this.set({nameList : nameList});
return nameList.fetch()

现在我们从 importNameList 返回一个延迟,我们可以使用它来保证在渲染之前完成获取:

this.deferred = courseView.model.importNameList('students.txt');
this.deferred.done(function() { courseView.render() });

我认为这应该可以满足你的要求,尽管我还没有实际测试过。

关于javascript - BackboneJS - 监听嵌套模型的变化,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12127367/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com