gpt4 book ai didi

javascript - 不了解其容器的主干 View 、通过 AJAX 获取的模型、没有 UI/UX 权衡和可维护的代码

转载 作者:行者123 更新时间:2023-11-28 06:07:23 25 4
gpt4 key购买 nike

由于我不完全确定我的问题实际上在哪个级别上得到最好的解决,所以我想总结一下我所走的道路以及我首先尝试的事情:

这或多或少与 $el 有关(我认为)。

正如大多数基本 Backbone 示例所述,我首先在其 View 中定义 $el,例如

Invoice.InvoiceView = Backbone.View.extend({
el: $('#container'),
template: ..,
..
});

感觉不对, View 应该了解其父级(=容器)。 http://coenraets.org/blog/2012/01/backbone-js-lessons-learned-and-improved-sample-app/上写的“将 View 与其他 DOM 元素分离”段落)完美地用语言表达了它。

按照本文的建议,我转而在调用 render() 方法时将 $el 传递给 View 。示例:

$('#container').html( new WineListView({model: app.wineList}).render().el );

到目前为止一切顺利 - 但现在 render() 被调用,虽然它可能不应该(还)被调用。

例如, View 在其initialize()例程中异步获取模型。添加到 resetsync 的绑定(bind)(例如 this.model.bind('sync', this.render, this))可确保,一旦获取模型,render() 肯定会被调用,但是如上所述,在尚未获取模型时,render() 仍然可能被调用

不太好,但是工作(TM),我通过检查模型的主键是否存在来解决这个问题:

render: function() {
if(this.model.get('id')) {
...
}

但是,我没想到的是 - 如果它确实没有记录(至少我没有找到任何相关内容),我认为它确实应该是 - 获取操作似乎不是原子的。虽然主键(“id”)可能已经是模型的一部分,但其余部分可能还不是。因此不能保证模型完全以这种方式获取。但无论如何,整个检查似乎都是错误的,所以我做了一些研究,并得到了 deferred.done 回调,这听起来正是我正在寻找的,所以我的代码变成了这样:

render: render() {
var self = this;
this.model.deferred.done(function() {
self.model.get('..')
};
return this;
}
..
$('#container').html( new WineListView({model: app.wineList}).render().el);

它有效!不错吧?呃……不是真的。从运行时流程的 Angular 来看,这可能很好,但该代码相当麻烦(温和地说......)。但我什至会咬紧牙关,如果没有那么小的细节,这段代码会立即设置(=替换) View ,但稍后填充它(由于延迟) .

假设您有两个(全页) View ,一个显示和一个编辑 - 并且您希望立即在这两个 View 之间切换(例如,在点击保存编辑 View 中,它会变成显示 View 。但是使用上面的代码它会立即设置(=重置) View 并且<一旦 deferred 触发(例如,一旦获取模型完成),strong>then 就会渲染其内容。这可能是短暂的闪烁或较长的空白过渡页。不管怎样,都不酷。

所以,我想我的问题是:如何实现不知道其容器的 View ,涉及需要获取的模型,应按需渲染的 View (但仅在获取模型后完全),无需接受 UI/UX 权衡,并且 - 锦上添花 - 最终拥有可维护的代码。

最佳答案

首先,您发现的第一个方法很糟糕( View 构造函数中的硬编码选择器)

第二个:new WineListView({model: app.wineList}).render().el非常常见,也不错。这需要你从 render 方法返回对 view 的引用,而且每个人似乎都遵循这一点,这是不必要的。

最好的方法(imo)是简单地将 View 元素附加到容器,就像这样

$('#container').html(new WineListView({model: app.wineList}).el);

WineListView 不需要知道它将在哪里使用,并且无论初始化 WineListView 是什么,都不需要担心何时渲染 WineListView View 实例:

因为 el 是对 HTML 元素的实时引用,因此 View 实例可以随时修改它,并且更改将反射(reflect)在它附加的任何位置。 DOM/当它附加到 DOM 中时。

例如,

WineListView = Backbone.View.extend({
initialize: function(){
this.render(); // maybe call it here
this.model.fetch({
success: _.bind(this,function(){
this.render(); // or maybe here
})
});
}
});
<小时/>

关于闪烁:这几乎与渲染或主干无关,只是您将一个元素替换为另一个元素,即使您的新 View 立即渲染,也会有一小段时间的空白。您应该使用转换、加载器等通用技术来处理此问题,或者避免切换元素(例如,将标签转换为同一 View 中的输入,而不需要切换 View )

关于javascript - 不了解其容器的主干 View 、通过 AJAX 获取的模型、没有 UI/UX 权衡和可维护的代码,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36710406/

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