gpt4 book ai didi

javascript - Backbone + RequireJS + Mediator Pattern 导致 View Logic 短路死循环

转载 作者:搜寻专家 更新时间:2023-11-01 04:19:11 24 4
gpt4 key购买 nike

我目前正在使用 Backbone.Mediator在我的 Backbone + RequireJS 项目中利用中介模式的好处;然而,我遇到了 Pattern 的一个特殊行为,我不太确定它是否是“设计使然”,或者更确切地说,不是 Mediator Pattern 的标准行为而是插件中的错误。

举个例子:

AMD 模块 1

var View1 = Backbone.View.extend({
...
events: {
'click div: switchList'
},
switchList: function() {
Backbone.Mediator.pub('list:switch');
}
});

AMD 模块 2

var View2 = Backbone.View.extend({
...
subscriptions: {
'list:switch': 'shrinkDiv'
},
shrinkDiv: function() {
Backbone.Mediator.pub('div:shrink');
this.shrinkAndMore();
}
});

return View2;

AMD 模块 3

define(function(require) {
var View2 = require(**AMD Module 2**);

var View3 = Backbone.View.extend({
...
subscriptions: {
'div:shrink': 'createSiblingDiv'
},
createSiblingDiv: function() {
this.siblingView = new View2();
this.$el.after(this.siblingView.$el);
this.siblingView.render();
}
});
});

我认为它会像这样工作:

                      **View1**.switchList();

Channel 'list:switch' │

**View2**.shrinkDiv();

├─┐
│ │ Channel 'div:shrink'
│ ↓
│ **View3**.createSiblingDiv();
│ │
│ └──→ "SiblingDiv created and rendered"

└────→ "View2 Div shrinked and more"

然而,事实是因为 SiblingDivView2 的另一个实例,它订阅了 Channel 'list:switch', SiblingDiv,紧接着它的创建,也将由仍在 channel “list:switch”上发生的事件信号触发(只有在执行 **View2**.shrinkAndMore(); 后才会停止)。

所以真正的代码流程是这样的:

                      **View1**.switchList();

Channel 'list:switch' │

**View2**.shrinkDiv(); ←──────────────────┐
│ │
├─┐ │
│ │ Channel 'div:shrink' │
│ ↓ │
│ **View3**.createSiblingDiv(); │
│ │ │
│ └──→ "SiblingDiv created and rendered" ─┘

└────→ "View2 Div shrinked and more"

无限循环...糟糕!

通过对我的代码进行一些修改,我能够让事情按照我的方式进行:

AMD 模块 2 retrofit

var View2 = Backbone.View.extend({
initialize: function() { // new code
if (this.options.subscriptions) { // new code
this.subscriptions = this.options.subscriptions; // new code
} // new code
}, // new code
...
subscriptions: {
'list:switch': 'shrinkDiv'
},
shrinkDiv: function() {
Backbone.Mediator.pub('div:shrink');
this.shrinkAndMore();
}
});

return View2;

AMD 模块 3 retrofit

define(function(require) {
var View2 = require(**AMD Module 2**);

var View3 = Backbone.View.extend({
...
subscriptions: {
'div:shrink': 'createSiblingDiv'
},
createSiblingDiv: function() {
this.siblingView = new View2({ // new code
subscriptions: {} // new code
}); // new code
this.$el.after(this.siblingView.$el);
this.siblingView.render();
}
});
});

但我很想知道是否考虑了无限循环行为(事件信号广播期间创建的新对象也将由该信号触发)中介模式方法论中的“标准”?或者这只是插件部分的错误?

最佳答案

这似乎是插件中的错误。看看this line .它将遍历在此 channel 中注册的所有事件。问题在于它会在调用每个已注册事件时停止,并且会在每个循环步骤中检查已注册事件数组的长度。所以发生的事情是:

  1. 你触发事件
  2. 您注册的事件名为
  3. 创建一个新实例并将其自身注册到 channel
  4. 这会将数组的长度增加一个
  5. 因此它不会结束循环,而是调用刚刚创建的 View 的监听器
  6. 回到 3。

将行更改为:

for (var i = 0, l =  channels[channel].length; i < l; i++) {

应该解决这个问题,因为您在开始时就得到了数组的长度。添加新元素不会以无限循环结束。

关于javascript - Backbone + RequireJS + Mediator Pattern 导致 View Logic 短路死循环,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12245468/

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