Knockout:避免绑定中的循环更新

2024-04-23

我有一个与接口交互的自定义​​绑定Scribe https://github.com/guardian/scribe,一个内容可编辑的所见即所得编辑器。当编辑器内容发生变化时,它会更新关联的可观察量,并在关联的可观察量发生变化时更新编辑器:

ko.bindingHandlers.editor = {
  init: function(element, valueAccessor) {
    var $element    = $(element),
        content     = ko.unwrap(valueAccessor()),
        scribe;

    // create a new editor instance
    scribe = new Scribe(element);

    // store it for later access in our 'update' handler
    $element.data('scribe', scribe);

    // set the initial editor content
    scribe.setContent(content);

    // update the observable whenever the editor changes
    scribe.on('content-changed', function() {
      var observable  = valueAccessor(),
          content     = scribe.getHTML();

      observable(content);
    });
  },
  update: function(element, valueAccessor) {
    var $element    = $(element),
        content     = ko.unwrap(valueAccessor());

    // update the editor content when the observable changes
    $element.data('scribe').setContent(content);
  }
};

问题是这样的:

  1. 用户在编辑器中输入
  2. 编辑器组件发送“已更改”事件
  3. 事件处理程序更新可观察的
  4. 绑定的“更新”处理程序被触发,将更改写回编辑器

通常这没什么大不了的,只是没有必要。但就我而言,editor.setContent具有将光标位置重置到输入开头的副作用 -你输入的所有内容都会被反转 http://gfycat.com/ShockingRequiredCormorant.

当且仅当可观察对象在应用程序中的其他位置发生更改时,我需要更新编辑器。我正在寻找的是一种避免使用最初源自编辑器本身的更改来更新编辑器的方法。

如何才能最好地避免这些循环更新?

Update:我找到了一种明显的方法来回避眼前的问题 - 在更新处理程序中,只需在进行更新之前将可观察内容与当前编辑器内容进行比较即可:

  if ($element.data('scribe').getHTML() !== content) {
    $element.data('scribe').setContent(content);
  }

如果只是为了避免不必要的更新调用,我仍然对一般答案感兴趣。


基于RP尼迈耶推荐 https://stackoverflow.com/questions/25685842/knockout-avoid-circular-updates-in-a-binding#comment40149514_25685842,我从绑定中移动了可观察 -> 组件更新功能update处理程序进入init处理程序:

ko.bindingHandlers.editor = {
  init: function(element, valueAccessor, allBindingsAccessor, viewModel, bindingContext) {
    var $element                = $(element),
        content                 = ko.unwrap(valueAccessor()),
        ignoreObservableChanges = false,
        scribe;

    scribe = new Scribe(element);

    $element.data('scribe', scribe);

    scribe.setContent(content);

    scribe.on('content-changed', function() {
      var observable  = valueAccessor(),
          content     = scribe.getHTML();

      ignoreObservableChanges = true;
      observable(content);
      ignoreObservableChanges = false;
    });

    valueAccessor().subscribe(function(newValue) {
      if (ignoreObservableChanges) {
        return;
      }

      scribe.setContent(newValue);
    });
  }
};

组件 -> 可观察更新器和可观察 -> 组件更新器现在共享ignoreObservableChanges标记在它们的范围内,因此前者可以指示后者何时跳过更新。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Knockout:避免绑定中的循环更新 的相关文章

  • 正确处理浏览器资源

    我有一个网络应用程序 可以在很长一段时间内动态加载数据 数据内有图像的链接 然后在浏览器中呈现这些图像 e g var object Name ko observable Foo Ref ko observable Bar ImageUrl
  • 使用 Knockout 将任何键(通过键码)绑定到操作

    我正在寻找一种方法将许多不同的键绑定到我的视图模型中的不同操作 功能 我找到了这个example http geekswithblogs net michelotti archive 2011 10 11 knockoutjs custom
  • KnockoutJS 的购物车逻辑(?)问题

    The Goal 制作动态产品列表 场景 我有一个包含产品的购物应用程序 当我点击add button的产品 我想在侧边栏中显示我添加的产品 问题总结 您只需阅读此内容 我的代码中有以下代码ProductsSummary Index csh
  • Knockout.js 与多个 Select2 绑定

    我的问题是 当我将 Select2 与 Multiple 和 Knockout 视图模型绑定时 选择其中一个选项后 第二次数据丢失 淘汰码 window load function ko bindingHandlers select2 in
  • 如何使用样式数据绑定?

    我在 KnockoutJS 中使用样式绑定时遇到困难 div div 渲染该模板
  • 如何使用淘汰赛映射插件添加新项目

    我正在尝试一个淘汰制图样本 我想我已经快完成了 我似乎无法向 viewModel foos 添加新的 Foo 谁能看到我在这里错过了什么 var Foo function data var self this self id data id
  • 淘汰赛和 jQuery 自动完成

    淘汰值绑定不适用于 jquery 自动完成 如何让它发挥作用 我有一个模板
  • JSON.stringify 使用 Knockout JS 变量的对象

    当前场景 function Employee data var self this variables this Forename ko observable data Forename this Surname ko observable
  • 为什么我不能在淘汰赛中将数据连接到可观察数组

    我正在尝试将服务器中的元素添加到淘汰赛中的可观察数组中 这是我的视图模型 function ArticlesViewModel var self this this listOfReports ko observableArray self
  • Kendo-Knockout:如何使窗口居中

    我正在使用 RPNiemeyer 的剑道淘汰库 我有一个剑道窗口 我在 html 中使用它 div div 我曾经这样将对话框居中 productionStates data kendoWindow center But as center
  • 如果依赖项位于 false 分支语句内,则计算将永远停止触发

    我遇到一个问题 即我的计算可观察量在一系列依赖项更改后停止触发 最后我发现了一点 如果在最近一次评估期间依赖项位于错误分支语句内 则下次将不会触发计算即使在评估完成之前条件变为真 这是一个示例 https jsfiddle net sgs2
  • jquery .html() 追加后绑定不起作用

    我有这个简单的 div div div 它是空的 现在我正在尝试附加这个HTML到上面的div div div
  • Knockout无法识别手动点击

    这是样本http jsfiddle net HhXGH 57 http jsfiddle net HhXGH 57 我正在通过 jquery 单击单选按钮 但 knockout js 无法识别它 它仍然显示第一个单击的值 p Send me
  • 如何将复选框绑定到值的倒数?

    我有一个情况 当我需要将一个复选框和另一个 DOM 元素的可见性绑定到我的 viewModel 的布尔属性的逆时
  • 在 KnockoutJS 中更改模型数据时,Javascript 内存泄漏

    我们正在构建一个相当大的单页应用程序 使用 KnockoutJS 作为 数据处理程序 问题是 当更改模型数据时 垃圾收集器不会处理旧模型 看起来如此 该应用程序有大约 12 个不同的模型 其中包含计算的可观察量 您可以使用它们检索关系 在
  • Knockout ObservableArray 不更新 HTML Foreach

    所以我有一个可以正常工作的 observablearray 但 UI 没有更新 我读过很多人遇到这种类型的问题 但我没有看到 所以 HTML 是 tbody tr td span class label label success Yup
  • 使用 Knockout 使用多个字段/列和控件来过滤 ViewModel 数据

    我是 KnockoutJS 的新手 但到目前为止我很喜欢它 我想做的是使用表单上的多个字段 列和控件来过滤我的视图模型的数据 但我不知道该怎么做 让我 希望 进一步解释一下 我有一个 viewmodel 可观察的数据数组 其中填充了来自后端
  • 强制使用原生 Knockout 模板

    我有一个需要 jQuery tmpl 的页面 但我想使用本机淘汰模板 data bind foreach Comments 属性 因为我已经包含了 jQuery tmpl 所以淘汰赛的本机模板被禁用 有没有办法可以强制使用本机功能 Than
  • 淘汰赛绑定,每个都可进行自定义

    我这里有一个情况 用于淘汰每个带有定制的绑定 这是我的代码 div div table tbody tr td td td td tr tbody table div div
  • Knockout.js 安全绑定

    我想使用带有淘汰赛的安全绑定 为此我使用敲除安全绑定 js https github com brianmhunt knockout secure binding 谁能解释一下为什么下面的代码不起作用 它会抛出一个错误 未捕获 淘汰 安全

随机推荐

  • 获取 PostgreSQL 的 RAISE NOTICE 的所有通知

    我有一个大数据库函数 它有多行这样 RAISE NOTICE some step completed 我想在我的 PHP 应用程序中获得所有这些通知 我只找到了pg last notice 只返回最后一个通知的函数 有什么办法可以获取所有通
  • 将列表值反映到另一个列表中?

    List
  • 在 python 中,如何使用 __str__ 逐行返回列表中的元素

    我有课Numberlist它需要一个数字列表 class Numberlist def init self number self number number def str self for i in self number print
  • iOS 10 通知内容扩展未加载

    我有一个简单的应用程序来处理推送通知 我的通知服务扩展正在运行 我可以发送带有图像 URL 的远程通知并加载它 我似乎无法让通知内容扩展正常工作 我已经看过多个教程 他们都说 只需从目标菜单创建一个通知内容扩展 然后在通知内容扩展 Info
  • ASP.NET MVC OutputCache 不适用于根 URI

    我正在学习 ASP NET MVC 并被一个问题困扰 在HomeController中 Index操作具有OutputCache属性 但它似乎不起作用 HandleError public class HomeController Cont
  • pytest 由于 ModuleNotFoundError 失败,但在使用“python -m pytest”时有效

    类似于这个OP的问题 https stackoverflow com questions 56755761 filenotfounderror when using python m pytest vs pytest 但反过来说 pytes
  • Reactjs this.refs 与 document.getElementById

    如果我只有基本表格 我还应该吗 this refs或者只是去document getElementById 我所说的基本是指 export default class ForgetPasswordComponent extends Reac
  • 使用渐变填充 SVG 形状

    如何将线性渐变和阴影应用于此图案
  • 熊猫选择倒数第二列,这也不是 nan

    我已尽可能多地清理数据并在 Pandas 数据框中读取它们 所以问题是不同的文件有不同的列数 但它总是倒数第二个非纳米列是我想要的 那么有什么办法可以把它们挑出来吗 这是数据的示例 f g h l 0 39994 29 568 29 569
  • 如何在SSRS图轴上跨越月份和年份?

    我真的很喜欢下面 SSRS 图表中 x 轴的月份和年份的跨度 我怎么做 将日期拆分为数据集中的几列 将这些列添加为条形图的类别组
  • Android ListView 填充内容而不移动 ListView 高度?

    我有一个 ListView 里面有一堆项目 如何使顶部和底部项目的顶部边距为 10dp 底部项目的底部边距为 10dp 现在我可以通过 ListView 上的填充或边距来做到这一点 但结果是 当您滚动时 ListView 的边缘现在距屏幕底
  • PHP中1个月代表多少天?

    我发现 php 中的月份加法和减法存在奇怪的问题 我的问题是 1 个月有相当于天数吗 如果是 这是所有编程语言的通用标准吗 举几个例子 echo date Y m d strtotime 2011 03 31 1 months 2011 0
  • node.js http 服务器,检测客户端何时断开连接

    我使用express 和node js 作为http 服务器 我存储响应对象 以便可以将事件流式传输到该通道上的客户端 有没有办法检测客户端何时断开连接 当我杀死我的客户端时 我仍然可以写入响应对象 而不会收到任何类型的异常 错误 看起来只
  • 安装 Rails 版本 3.2.15 时出现“Gem::RemoteFetcher::UnknownHostError”

    我之前已经在实时 ubuntu USB 上成功安装了 Rails 3 2 15 并具有数据持久性 现在我已经习惯了操作系统 Ubuntu 12 04 LTS 我已经将它安装在笔记本电脑上 并且正在安装我在实时 USB 中使用的东西 长话短说
  • 更改控制台大小

    Delphi中的简单问题 我创建了一个控制台应用程序 如果控制台窗口的高度少于 80 行 我需要将其高度更改为 80 行 这需要从代码中完成 并且实际上是在代码内有条件的 即 当发生错误时 它会增加控制台的大小 以便整个 巨大的 错误报告可
  • NSIS:在标签中插入链接

    假设我有以下 nsDialog 标签 单击 接受 即表示我同意示例的许可协议和隐私政策 您可以访问需要使用个人信息的功能 欲了解更多信息 请下载示例的内容政策 我想在此标签中插入链接 如下所示 单击 接受 即表示我同意示例的内容许可协议 h
  • 动画 GIF 作为 THREE.js 中的纹理

    我正在寻找一种在 THREE js 中使用 GIF 动画作为纹理的方法 我目前可以加载纹理 甚至是 GIF 格式 但它无法播放动画 有什么办法可以做到吗 我发现了一些像这样的链接 https github com JordiRos GLGi
  • 如何从 JavaScript 变量保存 png

    我在 javascript 变量中有一个以 base64 编码的图像 data image png base64 base64 data 编辑 我需要将该文件保存到磁盘而不要求访问者右键单击 编辑 是否可以 如何 提前致谢 此致 我知道这个
  • 如何从 Rails 中的 RSpec 测试调用应用程序帮助器方法?

    标题是不言自明的 我尝试过的一切都导致了 未定义的方法 澄清一下 我并不是想测试辅助方法 我正在尝试在集成测试中使用辅助方法 您只需在测试中包含相关的帮助程序模块即可使方法可用 describe foo do include ActionV
  • Knockout:避免绑定中的循环更新

    我有一个与接口交互的自定义 绑定Scribe https github com guardian scribe 一个内容可编辑的所见即所得编辑器 当编辑器内容发生变化时 它会更新关联的可观察量 并在关联的可观察量发生变化时更新编辑器 ko