【问题标题】:KnockoutJS data update writes internal function to UIKnockoutJS 数据更新将内部函数写入 UI
【发布时间】:2012-03-19 17:31:09
【问题描述】:

当我更新我的视图模型时,我遇到了这个奇怪的问题......基本上每次更新时,每个可观察对象似乎都有随机机会包含这些数据:

function observable() {    
        if (arguments.length > 0) {    
            // Write               

            // Ignore writes if the value hasn't changed    
            if ((!observable['equalityComparer']) || !observable['equalityComparer'](_latestValue, arguments[0])) {    
                observable.valueWillMutate();    
                _latestValue = arguments[0];    
                observable.valueHasMutated();    
            }

            return this; // Permits chained assignments    
        } else {    
            // Read    
            ko.dependencyDetection.registerDependency(observable); // The caller only needs to be notified of changes if they did a "read" operation

            return _latestValue;
        }    
    }

我使用 KnockoutJS 已经有一段时间了,但我从未见过这样的事情。我的猜测是它与我的模板绑定有关,但我真的不确定。我要深入研究它,但我想我会把它贴在这里,以防其他人遇到这个问题,或者有解决方案。就像我说的,它不会一直发生,只是偶尔发生。

//// 更多信息 ////

所以下面的 Matt 引用了这个(http://stackoverflow.com/questions/9763211/option-text-becomes-a-function-string-after-updated-with-fromjs),这大致是相同的问题。唯一的区别是我使用的是这样的原生模板绑定:

<div data-bind="template: {name: 'issueTemplate', data: incidents}"></div>

<script id="dashboardIssueTemplate" type="text/html">       
    <!--ko foreach: $data-->    
    <div data-bind="text: title"></div>
</script>

我的假设是,当您将 observableArray 传递到模板绑定器时,KnockoutJS 会自行处理展开。我知道在这个例子中我不能说“title()”,因为那不存在。我应该绑定 $root.title() 之类的命令吗?

//// 更多信息 ////

这个问题似乎是由于一个页面上有两个“applyBindings”。我的应用程序包含一个外部小部件,它在运行时将它的 DOM 添加到主机页面 DOM。该小部件正在使用 ko.applyBindings(vm, ROOTNODE) 语法,该语法应该允许主机页面运行它自己的 ko.applyBindings(hostVm)。

事实上,确实如此,并且每次刷新都能正常工作。然而,问题是当主机页面在没有刷新的情况下进行 viewModel 更新时。不知何故,UI 渲染在每个数据绑定节点上都吐出了这个内部函数。我已经通过 KnockoutJS 进行了调试,实际上确认 viewModel 和 rootNode 是正确的......实际绑定之外的东西正在接管。

【问题讨论】:

  • 如果它与您的绑定有关,您可能需要发布一个如何绑定的示例(最好是您看到错误发生的代码)
  • 同意。 jsfiddle (jsfiddle.net) 是一个不错的选择。
  • 是的,我通常会,但我对这个项目很感兴趣,我不能真正按照公司政策分享代码 :(。我会看看我是否不能把它复制到jsfiddle.
  • 实际上,我认为这可能与我的其他问题有关 [stackoverflow.com/questions/9775073/… 在我清除它后,新数据进入可观察数组的那一刻似乎发生了。我想我会玩一下映射插件,看看如何正确地做到这一点。
  • 没关系...看起来映射插件不像我需要的那样,因为它实际上替换了整个视图模型。我以为它只是创建了一个 observableArray :(.

标签: javascript knockout.js


【解决方案1】:

这与模板中附加到数据对象上的“()”有关。我发现在第一次渲染(页面加载)期间,像这样编写模板:

<div data-bind="template: {name: 'issueTemplate', data: incidents}"></div>

<script id="dashboardIssueTemplate" type="text/html">       
    <div data-bind="text: title"></div>
</script>

工作得很好。然而,一旦你在 observableArray 上运行更新,我的“title”对象就变成了那个函数。如果我使用这种风格编写模板:

<div data-bind="text: title()"></div>

似乎每次更新都有效。

我不确定为什么这是解决方案。从外观上看,传递给 Knockout binder 的数据对象在页面加载和更新时完全相同。我会将其作为答案发布,但在我了解为什么会发生这种情况之前,我不会将其标记为答案。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-04-16
    • 2016-01-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-07-12
    相关资源
    最近更新 更多