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

Knockout.js 如何使用Knockout将下拉列表绑定到选定项的属性?,knockout.js,Knockout.js,我想在列表中选择一项。这将打开一个下拉列表,我可以在其中更改所选项目的一个属性。下拉列表应预先选择属性的当前值 然而,我的实现并没有像我预期的那样工作。它不是显示项目值的下拉列表,而是相反的方式。项目的属性将更新为下拉列表中的选定值 function Scoring(valuePredefined) { this.name = ko.observable(valuePredefined); } AdjustmentEditViewModel

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

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

     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);
为什么这不能像我预期的那样工作?如何才能改变它以这种方式工作

模型 视图模型 看法

全源

评分=(函数(){
功能评分(预定义值){
var self=这个;
self.valuePredefined=ko.可观察(valueprefined);
}
回程记分;
})();
AdjustmentEditViewModel=(函数($){
功能调整EditViewModel(){
var self=这个;
self.selectedScoring=ko.observable();
var评分=[新评分({name:“Type 1”}),新评分({name:“Type 2”})];
self.scorings=ko.array(scorings);
self.getScoringName=函数(评分){
返回scoring.value预定义().name;
};
self.predefinedValues=[{name:“Type 1”},{name:“Type 2”}];
}
返回调整编辑视图模型;
})(jQuery);
$(窗口)。加载(函数(){
ko.applyBindings(新的AdjustmentEditViewModel());
});

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

     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);

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

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

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

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

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

谢谢您的回答,但它并没有一直工作。它们相同的原因是,当我在下拉列表中选择另一个值时,我希望列表中项目的名称发生更改。它们是否相互依赖?当您选择第一个下拉列表时,它将更改第二个下拉列表,反之亦然,对吗?是的,选择第一个下拉列表将更改第二个下拉列表中的选定项目。选择第二个下拉列表将更改第一个下拉列表中所选项目的名称。是否确定?我认为这将创建无限循环。选择第二个下拉列表时,我只希望更改第一个下拉列表中所选项目的选项文本,而不是值。我现在意识到我的例子在这一点上不是很清楚。在实际应用程序中,有几个属性可以更改,第一个下拉列表显示连接在一起的所有属性。
<!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>
     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);
self.getPredefinedName = function(predefinedID) {
    var predefined = ko.utils.arrayFirst(self.predefinedValues(), function (item) {
        return item.id() == predefinedID;
    });

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