编辑关于问题标题更改
原来的问题标题是这样的:
Angular 2/4 Observable - 如何修改在订阅内发出值的对象而不触发更多事件?
经过不是问题原因的广泛调查,但这里的评论中有关于如何解决该特定问题的建议。实际问题与同时拥有多个 ng2-dragula 订阅者有关,因此我更新了问题标题以反映这一点。
我正在使用 ng2-dragula 插件并订阅 dropModel 事件。
我面临的问题是,在订阅代码中,我需要通过重新排列模型中的其他项目来修改模型。这会导致 dropModel 再次触发 dropModel 事件 - 它显然认为因为我更改了用户执行拖放操作的列表中的模型位置,而不是我的代码。
我尝试了 take(1) 但这并没有解决问题 - 它只是不断地接受一个事件,所以当我在订阅中更改模型时,显然它会再次接受下一个 (1)。
这是代码:
this._dragulaService.dropModel.take(1).subscribe(() => {
// For ease, we just copy all the values into the model and then destroy
// the itemsControl, then patch all model values back to the form
// This is easier than working out which item was dragged and dropped where
// (and on each drop we want to save the model, so we would need to update it anyway)
this.itemsControl['controls'].forEach((formGroup, index) => {
this.template.template_items[index].sort = index; // ensures the API will always return items in the index order
console.log('copying ID', formGroup['controls'].id.value);
this.template.template_items[index].id = formGroup['controls'].id.value;
this.template.template_items[index].item_type = formGroup['controls'].item_type.value;
this.template.template_items[index].content = formGroup['controls'].content.value;
this.template.template_items[index].is_completed = formGroup['controls'].is_completed.value;
});
}
理想情况下,我想“抓取”第一个放置事件(用户发起),然后在订阅代码中,取消订阅或停止接收更多事件,然后处理模型,最后重新订阅。
我知道这有点奇怪——在订阅异步代码中,我需要以某种方式“暂停”订阅。尽管“暂停”并不完全正确——我实际上想以某种方式阻止触发新事件,直到我完成对当前事件的处理。暂停只会导致我处理自己的事件(如果有意义的话)。这可能吗?
笔记
dragula 在这里绑定的模型是 itemsControls 的动态数组,而不是通常意义上的纯数据模型。因此,为什么我要从表单控件中提取数据并插入到实际的数据模型中。
更新 1
我决定记录 Dragula 对绑定的 itemsControl(AbstractControls 数组)所做的事情。
在拖动之前,我记录了数组中的实际内容:
itemsControl is now this: (4) [FormGroup, FormGroup, FormGroup, FormGroup]
在 dropModel 订阅处理程序中,我记录了一个“dropped”事件和数组的长度。这是我拖放任何项目时的输出,始终是相同的输出:
dropped
length is 3
dropped
length is 3
dropped
length is 4
dropped
length is 5
dropped
length is 5
dropped
length is 4
dropped
length is 4
但是,如果我删除上面发布的代码(即,我不会触及底层数据模型),则输出如下:
dropped
length is 4
dropped
length is 4
因此,至少这证明了通过重新排序数据,我不仅会导致更多事件触发(正如我所怀疑的那样),而且还会产生奇怪的副作用,即控件数组的长度正在增加和减少(不知道为什么会这样) .
鉴于此输出,我需要一种仅对发出的最后一个事件采取行动的方法。
有没有办法只从 Observable 获取最后一个事件?
更新 2
据此,这里真正的问题是 ng2-dragula 不支持将 dropModel 绑定到 FormArray。但似乎有一种解决方法......仍在寻找!