无法绑定列表框中的选定值

时间:2015-01-03 10:37:53

标签: javascript asp.net-mvc knockout.js

我尝试创建一个双列表框,将项目从一个移动到另一个,然后最终将列表中的数据传回控制器。

作为一个javascript新手,我正在努力解决数据绑定问题。要将数据从一个列表框移动到另一个列表框,我创建了以下表单:

 <div class="container">
            <form role="form">
        <div class="container">
            <div class="row">
                <div class="col-md-5">
                    <div class="form-group">
                        <label for="SelectLeft">User Access:</label>
                        <select class="form-control" id="SelectLeft" multiple="multiple" data-bind="options : ownership, optionsText:function(item) { return item.FirstName + ' ' + item.LastName}, value:selectedItem">
                            @*<select class="form-control" id="SelectLeft" multiple="multiple">
                        </select>
                    </div>
                </div>   
                <div class="col-md-2">

                        <div class="btn-group-vertical">
                            <input class="btn btn-primary" id="MoveLeft" type="button" value=" << " data-bind="click: addItem" />
                            <input class="btn btn-primary" id="MoveRight" type="button" value=" >> " data-bind="click: removeSelected" />       
                        </div>

                </div>
                <div class="col-md-5">
                    <div class="form-group">
                        <label for="SelectRight">Owners:</label>
                        <select class="form-control" multiple="multiple" id="SelectRight" data-bind="options : availableOwners, optionsText:function(item) { return item.FirstName + ' ' + item.LastName}, value:selectedItem">
                        </select>
                    </div>
                </div>

            </div>                
        </div>
                <button type="submit" class="btn btn-default" value="Cancel" name="addEditUser" id="btnCancel" data-bind="click: cancel">Cancel</button>
                <button type="submit" class="btn btn-default" value="Submit" name="addEditUser" id="btnSubmit" data-bind="click: submit">Save</button>
    </form>
</div>

<script>
    var data=@(Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(Model)));
    var owners = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.AccessOwners));
    var availableOwners = @Html.Raw(Newtonsoft.Json.JsonConvert.SerializeObject(ViewBag.owners));
    function viewModel() {
        this.username=ko.observable(data.Username);
        this.password=ko.observable(data.Password);
        this.email=ko.observable(data.Email);
        this.isActive=ko.observable(data.IsActive);
        this.userId = ko.observable(data.UserId);
        this.ownership=ko.observable(owners);
        this.availableOwners = ko.observable(availableOwners)
        this.selectedItem = ko.observable();

        this.submit = function()
        {
            $.ajax({
                url: '@Url.Action("UserSave", "Admin")',
                type: 'POST',
                data: ko.toJSON(this),
                contentType: 'application/json',
            });
            window.location.href = url;
            return false;
        }

        this.cancel = function()
        {
            window.location.href = url;
            return false;
        }

        this.addItem = function () {
            if ((this.selectedItem() != "") && (this.ownership.indexOf(this.selectedItem()) < 0))
            {
                // Prevent blanks and duplicates
                this.ownership.push(this.selectedItem());
                this.availableOwners.removeAll(this.selectedItem());
            }
            this.selectedItem(""); // Clear the text box
        };

        this.removeSelected = function () {
            if ((this.selectedItem() != "") && (this.availableOwners.indexOf(this.selectedItem()) < 0))
            {
                this.ownership.removeAll(this.selectedItems());
                this.availableOwners.push(this.selectedItem());
            }
            this.selectedItem("");
        };

        this.sortItems = function() {
            this.ownership.sort();
            this.availableOwners.sort();
        };
    };
ko.applyBindings(new viewModel());
var url = $("#RedirectTo").val();

当我按下MoveLeft或MoveRight按钮时,出现以下错误:

Uncaught TypeError: undefined is not a function 
    (anonymous function) 
    jQuery.event.dispatch 
    elemData.handle

有没有人知道如何将列表框中的选定值传递给addItem或removeItem函数,以便从列表所有权中添加或删除对象?

谢谢!

2 个答案:

答案 0 :(得分:3)

niko使用Javascript,尤其是使用ko

,这将会很有趣

我将一些代码分叉,以便以更好的方式让您理解。

除了亲爱的Wayne Ellery提到的原因之外,您在此处遗漏的内容也很少,因为您必须使用selectedOptions 当有机会选择多个列表项时

您给我们undefined is not a function的错误是因为您正在选择多个列表项并试图推送它,这与ko推送无关的工作原因相反,您必须循环执行此操作。

点击此处查看selectedOptions Documentation

有一个小提琴权总是好的。在这里,我们去检查工作小提琴here

没有必要像你在click中所做的那样做一些额外的逻辑它可以用简单的可读方式完成所有提供的小提琴

查看型号:

    var vm=function() {
    var self=this;
    //observable's declaration    

    self.addItem = function () {
    ko.utils.arrayForEach(self.selectedItem1(),function(item){
    self.availableOwners.push(item);
        self.ownership.remove(item);
    });
    }

    self.removeSelected = function () {
    ko.utils.arrayForEach(self.selectedItem2(),function(item){
    self.ownership.push(item);
    self.availableOwners.remove(item)
    });
    };

};
ko.applyBindings(new vm());

查看:

<select  multiple="multiple" data-bind="options : ownership, optionsText:function(item) { return item.FirstName() + ' ' + item.LastName()}, selectedOptions:selectedItem1"></select>

 <input class="btn btn-primary" id="MoveLeft" type="button" value=" << " data-bind="click:removeSelected,enable:selectedItem2"  />

有关此问题,请与我们联系。

答案 1 :(得分:0)

可观察物的一些小问题。

selectedItem应初始化为空字符串:

this.selectedItem = ko.observable("");
所有权应该是一个observableArray。

this.ownership=ko.observableArray(owners);

您需要使用this.ownership()

评估所有权
if ((this.selectedItem() != "") && (this.ownership().indexOf(this.selectedItem()) < 0))
{
   // Prevent blanks and duplicates
   this.ownership.push(this.selectedItem());
   this.availableOwners.removeAll(this.selectedItem());
}
this.selectedItem(""); // Clear the text box