【问题标题】:Knockout JS: Display binded subList foreach meta items using exapnd optionKnockout JS:使用 exapnd 选项显示绑定的 subList foreach 元项目
【发布时间】:2017-03-31 19:36:15
【问题描述】:

这是我的数据结构。

=MetaData=
School
College
Home

=SubDetails=
School
    ClassRooms
    Library 
    OfficeRoom
College
    AdminOffice
    Departments
    Lab
    PlacementHall
Home
    LivingRoom
    StudyRoom
    Hall
    DiningHall
    Portico

将使用下拉菜单选择元数据值。例如,如果学校是从下拉菜单中选择的值,则显示区域应显示为:

+ school x

在我的情况下,单击 + 展开图标后,它应该会列出数据中的详细信息。

- School x
    ClassRooms
    Library 
    OfficeRoom

例如,如果我不断选择多个项目,比如学校、学院、家庭等

- School x
    ClassRooms
    Library 
    OfficeRoom
+ College x
- Home x
    LivingRoom
    StudyRoom
    Hall
    DiningHall
    Portico

我试过的代码:

HTML:

<div class="DataDisplay">
    <!-- ko foreach: selectedMetaDataList -->
    <span class="metaHeader">
            <span>
                <a href="#" data-bind="click: $parent.expandMetaData"><i class="fa fa-plus" style="padding-right: 3px;"></i></a>
                <span data-bind="text: $data"></span>
                <span class="combineImgText">
                    <img data-bind="click: $parent.remove" class="delfilter" src="@Url.Content("~/Content/images/icon_x_purple_on.png")" width="15" height="15" />
                </span>
            </span>
        </span><br />
    <!-- /ko -->
    <span class="subDetails" style="display: none">
        <!-- ko foreach: selectedSubDetailsList -->
        <span data-bind="text: $data" style="margin-left:25px"></span><span class="combineImgText">
            <img data-bind="click: $parent.remove" class="delfilter" src="@Url.Content("~/Content/images/icon_x_purple_on.png")" width="15" height="15" />
        </span><br />
        <!-- /ko -->
    </span>                             
</div>

JS:

if(//matching condition)
{
    selectedMetaDataList.push(selectedMetaData().toString()); //ko.observableArray([])
    selectedSubDetailsList.push(value[i]); //ko.observableArray([])
}

expandMetaData: function () {          
    expandData($(".subDetails").is(':visible') ? true : false);
    $(".subDetails").toggle();
},

问题是如果我选择了多个,那么只有最后添加的元素(如果可扩展)并且它包含先前选择的项目的所有子详细信息。我的问题是如何绑定特定的选定元数​​据以显示其子详细信息内容。过去两天我一直在为此苦苦挣扎:(

任何建议都会有所帮助!

【问题讨论】:

  • 你能创建一个小提琴吗?
  • 您没有显示足够的代码。使代码示例能够重现问题。然后,您可以删除有关您的数据库结构的所有屏幕截图和详细信息,因为它们并不是真正需要回答问题。
  • 好的,让我为此添加一个小提琴

标签: javascript jquery html css knockout.js


【解决方案1】:

在不查看您的视图模型的情况下,我能给您的最佳建议是:

  • 您的视图模型不必复制您的数据结构。它们是您的数据和视图之间的一层,因此您可以做出有益于您想要呈现事物的方式的更改。
  • 不要使用jQuery来隐藏/显示东西,使用knockout的默认数据绑定:visiblecss

为了说明这些要点:

  • 一个视图模型,其中包含对内部主要类别的详细信息的引用
  • visible 绑定隐藏和显示
  • 视图模型中的 expanded 状态会自动更新 UI 的多个部分

var metaData = [
  "School",
  "College",
  "Home"
];

var subDetails = {
  School: [
    "ClassRooms",
    "Library",
    "OfficeRoom"
  ],
  College: [
    "AdminOffice",
    "Departments",
    "Lab",
    "PlacementHall"
  ],
  Home: [
    "LivingRoom",
    "StudyRoom",
    "Hall",
    "DiningHall",
    "Portico"
  ]
};

// An important purpose of this view model is to include details _inside_ a meta item
var MetaViewModel = function(label) {
  // Expanded is used to bind to the visiblity of the details
  this.expanded = ko.observable(false);
  
  // Add a '+' or '-' sign based on expanded state
  this.label = ko.pureComputed(function() {
    return (this.expanded() ? "- " : "+ ") + label;
  }, this);
  
  // Here, we add the details to the item
  this.details = ko.observableArray(subDetails[label]);
  
  // Toggle flips the state of expanded
  this.toggle = function() {
    this.expanded(!this.expanded());
  }.bind(this);
  
  // Removes a detail from the item's details list
  this.remove = function(str) {
    this.details.remove(str);
  }.bind(this);
};

MetaViewModel.create = function(label) { return new MetaViewModel(label); };

var viewModel = {
   meta: metaData.map(MetaViewModel.create) // Creates a new viewmodel for each meta data category
}

ko.applyBindings(viewModel);
<script src="https://cdnjs.cloudflare.com/ajax/libs/knockout/3.2.0/knockout-min.js"></script>
<ul data-bind="foreach: meta">
  <li>
    <div data-bind="text: label, click: toggle"></div>
    <ul data-bind="foreach: details, visible: expanded">
      <li data-bind="text: $data + ' X', click: $parent.remove"></li>
    </ul>
</ul>

【讨论】:

  • 太棒了。谢谢mcuh :)
猜你喜欢
  • 2015-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-07-05
  • 2012-02-24
  • 2012-07-14
  • 2014-01-08
  • 2012-11-04
相关资源
最近更新 更多