在MVC ActionLink中使用Knockout绑定

时间:2012-08-10 02:36:08

标签: asp.net-mvc data-binding knockout.js asp.net-mvc-4 html.actionlink

我正在尝试使用KnockoutJS和MVC 4,以便在表格的第一列中显示一个包含ActionLink定义的表。显示数据本身非常简单,我在那里没有任何问题。我遇到的问题是生成ActionLink

我已经看了Use MVC helpers inside jquery.tmpl templates,但是那里的解决方案没有使用淘汰模板并且将Url插入到模型对象中是不可行的(将使用用于创建视图模型的app域模型对象广泛地通过申请)。

表格定义:

<table>
    <tbody data-bind="template: { name: 'dmuTableDetail', foreach: tables() }"></tbody>
</table>

tables是一个可观察的数组,因此是parens)。

淘汰赛模板定义:

<script id="dmuTableDetail" type="text/html">
    <tr>
        <td>@Html.ActionLink("Details", "Details", "DMUTableCategory", new { @Id = ??? } )</td>
        <td data-bind="text:TableId"></td>
        <td data-bind="text:TableName"></td>
    </tr>
</script>​

视图模型定义:

var PageViewModel = function () {
    self = this;

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

    self.readItems = function () {
        self.tables(jQuery.parseJSON('[{"TableId":1001, "TableName":"Table#1"},{"TableId":1002, "TableName":"Table#2"}]'));
    }
}

$(document).ready(function () {
    vm = new PageViewModel();
    self.readItems('');
    ko.applyBindings(vm);
});

(实际代码执行Ajax调用来检索数据,但上面的代码也证明了这个问题。)

无论我用???代替什么,我都无法获得要插入href的TableId字段的值。

非常感谢任何帮助。

三江源。

2 个答案:

答案 0 :(得分:7)

谢谢Eric,你让我想到了一个锚元素并绑定了href属性。

似乎答案比预期的要容易一些(通常是!)。

表格定义:(与原始问题相同)

<table>
    <tbody data-bind="template: { name: 'dmuTableDetail', foreach: tables() }"></tbody>
</table>

淘汰模板定义:(更改为href属性的绑定)。

<script id="dmuTableDetail" type="text/html">
    <tr>
        <td><a data-bind="attr: { 'href': '@Url.Action("Details", new RouteValueDictionary() { { "Controller", "DMUTableCategory" } } )/' + TableId }">Details</a></td>
        <td data-bind="text:TableId"></td>
        <td data-bind="text:TableName"></td>
    </tr>
</script>?

视图模型定义:(与原始问题相同)

var PageViewModel = function () {
    self = this;

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

    self.readItems = function () {
        self.tables(jQuery.parseJSON('[{"TableId":1001, "TableName":"Table#1"},{"TableId":1002, "TableName":"Table#2"}]'));
    }
}

$(document).ready(function () {
    vm = new PageViewModel();
    self.readItems('');
    ko.applyBindings(vm);
});

您实际上并不需要RootValueDictionary但我已将其包含在内,以便人们可以看到如何更改请求发送到的控制器。

答案 1 :(得分:3)

Knockout完全绑定在客户端,这是在MVC为您的页面呈现HTML并将其发送回原始浏览器之后。

如果您希望您的Knockout模板能够使用在服务器上生成的URL,那么您将必须采用类似于以下内容的一些聪明策略:

CSHTML:

@{
    // create a dummy URL that you can use as a template
    string hrefFormat = Url.Action("Details", "DMUTableCategory", new { id = "{ID}" });
}

<script type="javascript">
    // a global string (but you can put it where ever you need to)
    var _hrefFormat = @Html.Raw(hrefFormat)
<script>

JS:

self.readItems = function () {
    self.tables(jQuery.parseJSON('[{"TableId":1001, "TableName":"Table#1"},{"TableId":1002, "TableName":"Table#2"}]'));


    // loop through the 'tables' and add a new 'href' property to each for binding
    ko.utils.arrayForEach(self.tables(), function(table){
         table.href = _hrefFormat.replace("{ID}", table.TableId);
    });
}

你的KO Tmpl,你将每个表对象的'href'属性绑定到a标签的href属性:

<script id="dmuTableDetail" type="text/html">
    <tr>
        <td><a data-bind="attr: { 'href': href }">Details</a></td>
        <td data-bind="text:TableId"></td>
        <td data-bind="text:TableName"></td>
    </tr>
</script>​