使用带有MVC 4的Knockout.js填充选择选项

时间:2016-06-06 13:26:34

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

我是knockout.js的初学者。我无法获得选择的选项以填充MVC 4视图。这是我的代码。

(控制器中的断点显示正确填充视图包的数据。该列表每个项目只包含两个字段:在控制器中创建SelectList时显示。)

控制器:

public ActionResult Index()
{
    List<Brewery> breweries = new List<Brewery>(_commonProvider.GetBreweryList());
    ViewBag.Breweries = new SelectList(breweries.AsEnumerable(), "BreweryCode", "BreweryDescription");
    return View();
}

观点:

/*** html stuff ***/
<select class="ui-select" id="BrewerySelect" name="BrewerySelect" data-bind="options: GetBreweries,
                                                                             optionsText: BreweryDescription,
                                                                             optionsValue BreweryCode,
                                                                             value: selectedBrewery,
                                                                             optionsCaption: Select a Brewery"></select>

/*** javascript stuff ***/
@section footer {
    @Scripts.Render("~/bundles/viewscripts-js")
    <script type="text/javascript">
        var config = {
            GetBrewery: '@Url.Action("GetBrewery")',
            GetLine: '@Url.Action("GetLine")',
            GetUrl: '@Url.Action("GetUrl")'
        };

        var data = {
            Brewery: "@ViewBag.Breweries",
            Date: '@DateTime.Today.ToString("MM/dd/yyyy")'
        };

        var viewModel = DashboardReportViewModel(config, data);
        ko.applyBindings(viewModel);


    </script>
}

ViewModel

var DashboardReportViewModel = function (config, originalData) {
    var self = this;

    self.GetBreweries = ko.observableArray([originalData.Breweries]);
}

我也试过了:

var DashboardReportViewModel = function (config, originalData) {
    var self = this;

    self.GetBreweries = ko.observableArray([]);

    var loadBreweries = function () {
        self.GetBreweries(originalData.Brewery);
    }

    loadBreweries();
}

2 个答案:

答案 0 :(得分:1)

为了澄清,ViewBag将保存一个对象或对象数组,但是当您从视图中调用该ViewBag属性时,它将在该属性上调用ToString

因此,

"@ViewBag.Breweries"

与写作相同

"@ViewBag.Breweries.ToString"

除非你覆盖SelectList.ToString(),否则所有你将得到的是完全合格的班级名称。

首选方法 - 正如您现在所做的那样 - 将Breweries公开为可检索数据(JSON,XML,等。)并异步检索,但您也可以添加一个名为SelectList.ToJson()的扩展方法,该方法会返回SelectList格式的内容,以便您可以在视图上的<script>标记中轻松输出格式。

答案 1 :(得分:0)

在发现发送Viewbag只是导致传递一个字符串之后,我将控制器BreweryList构建移动到一个单独的ActionResult并使用ajax来调用它。

更改

查看:

 <select class="ui-select" id="BrewerySelect" name="BrewerySelect" data-bind="options: GetBreweries,
                                                                              optionsText: 'Text',
                                                                              optionsValue: 'Value',
                                                                              optionsCaption: 'Select a Brewery'"></select>

控制器:

    public ActionResult Index()
    { 
        return View();
    }

    [HttpGet]
    public ActionResult GetBreweries()
    {
        List<Brewery> breweries = new List<Brewery>(_commonProvider.GetBreweryList());
        SelectList breweryList = new SelectList(breweries, "BreweryCode", "BreweryDescription");
        return Json(breweryList, JsonRequestBehavior.AllowGet);
    }

视图模型:

var DashboardReportViewModel = function (config, originalData) {
    var self = this;

    self.GetBreweries = ko.observableArray([]);    

    var loadBreweries = function () {
        $.ajax({
            url: config.GetBreweries,
            type: "GET",
            error: function (xhr, status, error) {
                alert(xhr.responseText);
            },
            success: function (data) {
                self.GetBreweries(data);
            },
            cache: false
        });
    };
    loadBreweries();

};

没有其他改变。