options single use value from json - Knockout JS



我有数据来自另一个视图模型,我在一个下拉菜单中显示它。我需要来自其他视图模型的每个选项每行都是唯一的,所以一旦用户向列表中添加了一个项目,该选项就不再可用了。

这里是工作小提琴:http://jsfiddle.net/QTUqD/9/

    window.usrViewModel = new function () {
    var self = this;
    window.viewModel = self;
    self.list = ko.observableArray();
    self.pageSize = ko.observable(10);
    self.pageIndex = ko.observable(0);
    self.selectedItem = ko.observable();    
    self.extData = ko.observableArray();    
    extData = ExtListViewModel.list();

    self.edit = function (item) {
        if($('#usrForm').valid()) {
        self.selectedItem(item);
        }
    };
    self.cancel = function () {
        self.selectedItem(null);
    };
    self.add = function () {
        if($('#usrForm').valid()) {
        var newItem = new Users();
        self.list.push(newItem);
        self.selectedItem(newItem);
        self.moveToPage(self.maxPageIndex());
        };
    };
    self.remove = function (item) {
            if (confirm('Are you sure you wish to delete this item?')) {
                    self.list.remove(item);
                    if (self.pageIndex() > self.maxPageIndex()) {
                        self.moveToPage(self.maxPageIndex());
                    }
            }
            $('.error').hide();
    };
    self.save = function () {
        self.selectedItem(null);
    };
    self.templateToUse = function (item) {
        return self.selectedItem() === item ? 'editUsrs' : 'usrItems';
    };
    self.pagedList = ko.dependentObservable(function () {
        var size = self.pageSize();
        var start = self.pageIndex() * size;
        return self.list.slice(start, start + size);
    });
    self.maxPageIndex = ko.dependentObservable(function () {
        return Math.ceil(self.list().length / self.pageSize()) - 1;
    });
    self.previousPage = function () {
        if (self.pageIndex() > 0) {
            self.pageIndex(self.pageIndex() - 1);
        }
    };
    self.nextPage = function () {
        if (self.pageIndex() < self.maxPageIndex()) {
            self.pageIndex(self.pageIndex() + 1);
        }
    };
    self.allPages = ko.dependentObservable(function () {
        var pages = [];
        for (i = 0; i <= self.maxPageIndex() ; i++) {
            pages.push({ pageNumber: (i + 1) });
        }
        return pages;
    });
    self.moveToPage = function (index) {
        self.pageIndex(index);
    };
};
ko.applyBindings(usrViewModel, document.getElementById('usrForm'));
function Users(fname, lname, email, phone, access, usrExtVal){
    this.fname = ko.observable(fname);
    this.lname = ko.observable(lname);
    this.email = ko.observable(email);
    this.phone = ko.observable(phone);
    this.access = ko.observable(access);
    this.usrExtVal = ko.observableArray(usrExtVal);   
}

<form id="usrForm">
<h2>Users</h2>
<table class="table table-striped table-bordered">
    <thead>
        <tr>
            <th>First Name</th>
            <th>Last Name</th>
            <th>Email</th>
            <th>Phone Number</th>
            <th>Access</th>
            <th>Extension</th>
            <th style="width: 100px; text-align:right;" />
        </tr>
    </thead>
   <tbody data-bind=" template:{name:templateToUse, foreach: pagedList }"></tbody>
</table>
<p class="pull-right"><a class="btn btn-primary" data-bind="click: $root.add" href="#" title="edit"><i class="icon-plus"></i> Add Users</a></p>
<div class="pagination pull-left">
    <ul><li data-bind="css: { disabled: pageIndex() === 0 }"><a href="#" data-bind="click: previousPage">Previous</a></li></ul>
    <ul data-bind="foreach: allPages">
        <li data-bind="css: { active: $data.pageNumber === ($root.pageIndex() + 1) }"><a href="#" data-bind="text: $data.pageNumber, click: function() { $root.moveToPage($data.pageNumber-1); }"></a></li>
    </ul>
    <ul><li data-bind="css: { disabled: pageIndex() === maxPageIndex() }"><a href="#" data-bind="click: nextPage">Next</a></li></ul>
</div>
<br clear="all" />
    <script id="usrItems" type="text/html">
   <tr>
        <td data-bind="text: fname"></td>
        <td data-bind="text: lname"></td>
        <td data-bind="text: email"></td>
        <td data-bind="text: phone"></td>
        <td data-bind="text: access"></td>
        <td data-bind="text: usrExtVal"></td>
        <td class="buttons">
            <a class="btn" data-bind="click: $root.edit" href="#" title="edit"><i class="icon-edit"></i></a>
            <a class="btn" data-bind="click: $root.remove" href="#" title="remove"><i class="icon-remove"></i></a>
        </td>
    </tr>
</script>
 <script id="editUsrs" type="text/html">
   <tr>
        <td><input data-errorposition="b" class="required" name="fname" data-bind="value: fname" /></td>
        <td><input data-errorposition="b" class="required" name="lname" data-bind="value: lname" /></td>
        <td><input data-errorposition="b" class="required" name="email" data-bind="value: email" /></td>
        <td><input data-errorposition="b" class="required" name="phone" data-bind="value: phone" /></td>
        <td><select data-bind="value: access"><option>Employee</option><option>Administrator</option><option>PBX Admin</option><option>Billing</option></select></td>
        <td><select data-bind="options: $root.extOptions, optionsText: 'extension', value: usrExtVal"></select></td>
        <td class="buttons">
            <a class="btn btn-success" data-bind="click: $root.save" href="#" title="save"><i class="icon-ok"></i></a>
            <a class="btn" data-bind="click: $root.remove" href="#" title="remove"><i class="icon-remove"></i></a>
        </td>
   </tr>
</script>
</form>

我不确定这是否是您正在寻找的,但这里有一个提琴,计算基于那些已经在使用的可用值:

http://jsfiddle.net/jearles/QTUqD/11/

,

HTML

<select data-bind="options: $root.availableExtData, optionsText: 'extension', value: usrExtVal"></select>

JS

self.availableExtData = ko.computed(function() {
    var inUse = [];
    if (!self.selectedItem()) return inUse;
    ko.utils.arrayForEach(self.list(), function(item) {
        if (inUse.indexOf(item.usrExtVal().extension) == -1 && self.selectedItem() != item) inUse.push(item.usrExtVal().extension);
    });
    return ko.utils.arrayFilter(self.extData(), function(item) {
        return inUse.indexOf(item.extension) == -1;
    });
});

,

代码确保当选择项被编辑时,它的当前值是可用的。此外,一旦有了所有可用值的行,我也不显示添加按钮。

用可用的选项创建一个computed observable,它会从完整的列表(extData)中过滤掉那些已经被分配给一个项目的选项——除了被选中的项目使用的选项——然后将select字段的选项绑定到计算的列表,而不是整个列表。

最新更新