【问题标题】:Knockout computed binding not updating the template name淘汰赛计算绑定不更新模板名称
【发布时间】:2014-10-01 18:46:57
【问题描述】:

我正在从 JQuery 绑定转移到 Knockout,以使 UI 与数据的同步更容易。我对淘汰赛相当陌生,但为了保持整洁,我正在使用 Requirejs 淘汰赛。

因此,在我的一个模块中,我尝试使用模板来更改信息栏并将模板名称绑定到计算出的 observable。但是计算出来的 observable 并没有更新 UI 中的模板名称。

<div data-bind="template: { name: baseData.printListTemplate }"></div>

<script type="text/html" id="inPrintList">
    <span>
        <span>In </span>
        <a href="#" class="managePrintList">Print List</a>
    </span>

    <a href="#" data-bind="click: switchInPrintList">sw</a>
</script>

<script type="text/html" id="notInPrintList">
    <span>
        <span>Add to </span>
        <a href="#" class="managePrintList">Print List</a>
    </span>

    <a href="#" data-bind="click: switchInPrintList">sw</a>
</script>

以上是我的 html 代码和 Knockout 模板。

以下代码是我的 Knockout 模块

在 baseData 中,我计算了 printListTemplate 的 observable,返回了用于打印列表指示器的模板名称。

switchInPrintList 更改 inPrintList 可观察对象,更改后 ko.computed 函数运行并返回正确的字符串,但在这些之后 UI 不会更新。

define(['knockout', 'Modules/utils', 'Modules/Shared/kodialog'],
    function (ko, utils, kodialog) {

        var baseData = function (data) {
            var self = this;

            self.inPrintList = ko.observable(false);

            ko.mapping.fromJS(data, {}, self);

            self.printListTemplate = ko.computed(function () {
                if (self.inPrintList())
                    return "inPrintList";
                else
                    return "notInPrintList";
            }, this);
        }

        var baseDataMapping = {
            create: function (options) {
                return new baseData(options.data);
            }
        }

        return function player() {
            var self = this;

            var utils = new utils();

            self.baseData = new baseData();

            self.dialog = new kodialog();

            self.renderMP = function (contentId) {
                self.dialog.openDialog();
                $.ajax({
                    type: "GET",
                    url: "/Home/mpdata",
                    dataType: 'json',
                    crossDomain: true,
                    data: { contentid: contentId },
                    success: function (jsonResult) {
                        self.baseData = ko.mapping.fromJS(jsonResult, baseDataMapping);
                        self.dialog.rendered(true);
                    }
                });
            }
            self.switchInPrintList = function () {
                if (self.baseData.inPrintList())
                    self.baseData.inPrintList(false);
                else
                    self.baseData.inPrintList(true);
            }
        }
    });

【问题讨论】:

  • 对我来说似乎很好。这是一个fiddle,其中包含您的代码,正在运行。
  • 好吧,我猜映射插件会破坏绑定。有什么想法吗?
  • 我删除了 baseDataMapping 并手动设置了服务器数据,正如您的小提琴示例所暗示的那样,它现在可以正常工作了。
  • @Azadrum,你解决了这个问题吗?
  • @Ilya Luzyanin,很好地解决了......当我摆脱映射并手动完成绑定时,它起作用了。我也尝试了你的解决方案,但它是一样的。我想我需要更多时间来了解淘汰赛绑定是如何工作的,所以我绕过了这个问题让事情发生了变化。

标签: javascript knockout.js requirejs javascript-objects


【解决方案1】:

我认为问题在于您在成功回调中重新分配baseData,而您只需要相应地更新它的属性。对于这种情况,ko.mapping.fromJS() 方法还有另一个重载,它将第三个参数作为更新目标,哪些属性应该被更新。参见documentation,“指定更新目标”。

所以尝试像这样重写你的成功回调:

success: function (jsonResult) {
    ko.mapping.fromJS(jsonResult, baseDataMapping, self.baseData);
    self.dialog.rendered(true);
}

【讨论】:

  • 我停止使用映射插件,但如果我这样做了,你是对的。我应该用 serverData 更新虚拟机而不是重新分配。
猜你喜欢
  • 2016-06-21
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-10-30
  • 1970-01-01
  • 1970-01-01
  • 2019-06-02
  • 1970-01-01
相关资源
最近更新 更多