淘汰阵列单选按钮和/或基于droplist

时间:2016-10-03 22:13:59

标签: asp.net-mvc knockout.js

现在我正在从可观察数组中填充单选按钮,

def create
  @post = Post.find(params[:post_id])
  @comment = @post.comments.new(comment_params)
  @comment.user = current_user
  if @comment.save
    redirect_to [@post, @comment]
  else
    render_action :new
  end
end

private

# Don't forget to use require/permit to make sure the user can't 
# fake up the user/post id fields themselves out of whole-cloth
def comment_params
  # or whatever your permitted comment-fields are.
  params.require(:comment).permit(:content)
end

如果我想为Make' Honda'填充单选按钮。和制造丰田的下拉列表#39;怎么做?

基本上,我正在尝试从同一个可观察数组中填充两个不同的控件列表。

2 个答案:

答案 0 :(得分:0)

如果我明白你想要做什么,这里有一个例子,你可以做什么: 示例:https://jsfiddle.net/kyr6w2x3/85/

HTML:

    <div data-bind="foreach: Cars">
        <input type='radio' data-bind="checked :$parent.VehicleSelected ,checkedValue: Make, value:Id">
        <span data-bind="text: Make"></span>
        <select data-bind="foreach:Models,visible:IsSelected" >
          <option data-bind="text:Name , value:Id"></option>
        </select>
        <br />
    </div>

JS:

var data = [
{Id:1,Make :"TOYOTA",Model: [{Id:1,Name:"COROLLA"},{Id:2,Name:"CAMERY"},{Id:3,Name:"PERADO"}]},
{Id:2,Make :"HONDA",Model:[{Id:4,Name:"CIVIC"},{Id:5,Name:"ACCORD"},{Id:6,Name:"PILOT"}]},
{Id:3,Make :"NISSAN",Model:[{Id:7,Name:"SENTRA"},{Id:8,Name:"ALTIMA"},{Id:9,Name:"JUKE"}]}];

function AppViewModel() {
 var self = this ;
 self.Cars = ko.observableArray($.map(data, function (item) {
      return new CarItemViewModel(item);
 }));
  self.VehicleSelected = ko.observable();
  self.VehicleSelected.subscribe(function(newValue){
    ko.utils.arrayForEach(self.Cars(), function(item) {
        if (item.Make().toUpperCase() === newValue.toUpperCase()) {
            return item.IsSelected(true);
        }else{
           return item.IsSelected(false);
        }
    });
  })

}

var CarItemViewModel = function (data){
  var self = this ;
  self.Id = ko.observable(data.Id);
  self.Make = ko.observable(data.Make);
  self.Models = ko.observableArray($.map(data.Model, function (item) {
    return new ModelsItemViewModel(item);
  }));
  self.IsSelected = ko.observable(false);
}
var ModelsItemViewModel = function (data){
  var self = this ;
  self.Id = data.Id;
  self.Name = data.Name;
}
var appVM = new AppViewModel()
ko.applyBindings(appVM);

答案 1 :(得分:0)

我对你的问题的解释:

  • 您有一个包含所有数据的变量
  • 您希望呈现多个 UI元素,这些元素代表这些数据的子集

执行此操作的一种好方法是使用ko.computed来返回observableArray的过滤结果。一个例子:

var allCars = ko.observableArray([
  {"name":"CIVIC","make":"HONDA"},
  {"name":"SENTRA","make":"NISSAN"}];

var hondas = ko.computed(function() {
  return allCars().filter(function(car) {
    return car.make === "HONDA";
  });
});

因为计算使用了allCars observable,所以当源数据发生变化时会通知它。重新评估filter方法。在下面的代码段中,您可以看到您可以将新数据推送到源并自动放入正确的子集中!

&#13;
&#13;
var allCars = ko.observableArray([
  {"name":"CIVIC","make":"HONDA"},
  {"name":"ACCORD","make":"HONDA"},
  {"name":"PILOT","make":"HONDA"},
  {"name":"SENTRA","make":"NISSAN"},
  {"name":"ALTIMA","make":"NISSAN"},
  {"name":"JUKE","make":"NISSAN"}]);

var hondas = ko.computed(function() {
  return allCars().filter(function(car) {
    return car.make === "HONDA";
  });
});

var nissans = ko.computed(function() {
  return allCars().filter(function(car) {
    return car.make === "NISSAN";
  });
});

var otherBrands = ko.computed(function() {
  return allCars().filter(function(car) {
      return car.make !== "NISSAN" &&
        car.make !== "HONDA";
  });
});

var inputVM = {
  name: ko.observable(""),
  make: ko.observable(""),
  add: function() {
     allCars.push({
       name: this.name(),
       make: this.make().toUpperCase()
     }); 
  }
};

ko.applyBindings({ 
  hondas: hondas, 
  nissans: nissans,
  allCars: allCars,
  otherBrands: otherBrands,
  inputVM: inputVM
});
&#13;
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<h2>Honda</h2>
<ul data-bind="foreach: hondas">
  <li data-bind="text: name"></li>
</ul>
<h2>Nissan</h2>
<ul data-bind="foreach: nissans">
  <li data-bind="text: name"></li>
</ul>
<h2>Other brands</h2>
<ul data-bind="foreach: otherBrands">
  <li data-bind="text: name"></li>
</ul>
<h2>Add car</h2>
<div data-bind="with: inputVM">
  <label>
    Name:
    <input type="text" data-bind="value: name">
  </label>
  <label>
    Make:
    <input type="text" data-bind="value: make">
  </label>
  <button data-bind="click: add">Add</button>
</div>
&#13;
&#13;
&#13;