如何使用Knockout将下拉列表绑定到所选项的属性?

时间:2014-07-30 08:17:49

标签: knockout.js

我想在列表中选择一个项目。这将打开一个下拉列表,我可以在其中更改所选项目的其中一个属性。下拉列表应预先选择该属性的当前值。

但是,我的实现并没有像我预期的那样工作。而不是显示项目值的下拉列表,而是另一种方式。项目的属性将更新为下拉列表中的选定值。

为什么这不符合我的预期,怎么能改变这种方式呢?

模型

Scoring = (function () {
    function Scoring(valuePredefined) {
        var self = this;
        self.valuePredefined = ko.observable(valuePredefined);
    }

    return Scoring;
})();

视图模型

AdjustmentEditViewModel = (function ($) {
    function AdjustmentEditViewModel() {
        var self = this;

        self.selectedScoring = ko.observable();

        var scorings = [new Scoring({ name: "Type 1" }), new Scoring({ name: "Type 2" })];
        self.scorings = ko.observableArray(scorings);

        self.getScoringName = function (scoring) {
            return scoring.valuePredefined().name;
        };

        self.predefinedValues = [{ name: "Type 1" }, { name: "Type 2" }];
    }

    return AdjustmentEditViewModel;
})(jQuery);

视图

<select data-bind="options: scorings, value: selectedScoring, optionsText: function (item) { return getScoringName(item); }" size="5"></select>
<!-- ko if: selectedScoring -->
<select data-bind="options: predefinedValues, value: selectedScoring().valuePredefined, optionsText: function (item) { return item.name; }"></select>
<!-- /ko -->

完整来源

<!DOCTYPE html>
<html>
<head>
    <title></title>
    <script type="text/javascript" src="jquery-1.9.1.js"></script>
    <script type="text/javascript" src="knockout-3.1.0.js"></script>
    <script>
        Scoring = (function () {
            function Scoring(valuePredefined) {
                var self = this;
                self.valuePredefined = ko.observable(valuePredefined);
            }

            return Scoring;
        })();

        AdjustmentEditViewModel = (function ($) {
            function AdjustmentEditViewModel() {
                var self = this;

                self.selectedScoring = ko.observable();

                var scorings = [new Scoring({ name: "Type 1" }), new Scoring({ name: "Type 2" })];
                self.scorings = ko.observableArray(scorings);

                self.getScoringName = function (scoring) {
                    return scoring.valuePredefined().name;
                };

                self.predefinedValues = [{ name: "Type 1" }, { name: "Type 2" }];
            }

            return AdjustmentEditViewModel;
        })(jQuery);

        $(window).load(function () {
            ko.applyBindings(new AdjustmentEditViewModel());
        });
    </script>
</head>
<body>
    <select data-bind="options: scorings, value: selectedScoring, optionsText: function (item) { return getScoringName(item); }" size="5"></select>
    <!-- ko if: selectedScoring -->
    <select data-bind="options: predefinedValues, value: selectedScoring().valuePredefined, optionsText: function (item) { return item.name; }"></select>
    <!-- /ko -->
</body>
</html>

2 个答案:

答案 0 :(得分:0)

您将同一个observable绑定到两个下拉列表的值,而不是使用不同的可观察属性,并订阅第一个下拉列表中使用的第一个属性来更改其他下拉列表的值。

     function Scoring(valuePredefined) {
           this.name = ko.observable(valuePredefined);
     }

     AdjustmentEditViewModel = (function ($) {
      function AdjustmentEditViewModel() {
       var self = this;

       self.selectedScoring = ko.observable();
       self.selectedScoring2 = ko.observable();
       self.selectedScoring.subscribe(function (newValue) {
          self.selectedScoring2(newValue.name());
       });
       self.selectedScoring2.subscribe(function (newValue) {
          self.selectedScoring().name(newValue || newValue.valuePredefined().name);
       });
       var scorings = [new Scoring("Type 1"), new Scoring("Type 2")];
       self.scorings = ko.observableArray(scorings);

       self.predefinedValues = [{
          name: "Type 1"
          }, {
          name: "Type 2"
          }];
       }

      return AdjustmentEditViewModel;
    })(jQuery);

JsFiddle Demo

答案 1 :(得分:0)

我已经弄明白为什么它不起作用,问题是将下拉列表绑定到一个对象而不是一个原语,与此answer相同的解释。

为了解决这个问题,我选择只代表得分中的id。我在视图模型中创建了一个新函数来获取名称,仅用于在列表中显示它,如下所示:

self.getPredefinedName = function(predefinedID) {
    var predefined = ko.utils.arrayFirst(self.predefinedValues(), function (item) {
        return item.id() == predefinedID;
    });

    if (predefined) {
        return predefined.name();
    }
};

然后我使用了这个函数而不是直接绑定到valuePredefined属性。

相关问题