Using Knockout Bindings in ActionLink MVC

I am trying to use KnockoutJS and MVC 4 to display a table with ActionLink definitions in the first column of a table. The display of the data itself is extremely straightforward, and I have no problems. The problem is generating ActionLink .

I examined Using MVC helpers inside jquery.tmpl templates , but the solution does not use knockout templates there and inserting Url into the model object is impossible (application domain model objects used to create the presentation model will be widely used through the application).

Table definition:

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

( tables is an observable array, hence parens).

Knockout pattern definition:

 <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>​ 

View Model Definition:

 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); }); 

(the actual code makes an Ajax call to retrieve the data, but the code above also demonstrates the problem).

No matter what I replace ??? , I can’t get the value of the TableId field that I need to insert in href.

Any help would be greatly appreciated.

Thankyou.

+6
source share
2 answers

Thank you Eric, you made me think about the anchor and bind the href attribute.

The answer seems to be a little easier than expected (usually this!).

Table definition: (same as original question)

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

Knockout pattern definition: ( change href attribute binding ).

 <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>? 

View Model Definition: (same as original question)

 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); }); 

You don't really need a RootValueDictionary , but I turned it on so people can see how to change the controller the request is sent to.

+7
source

The knockout is fully contacted on the client side, which after MVC rendered the HTML for your page and sent it back to the original browser.

If you want your knockout template to be able to use the URL created on the server, you will have to use some smart strategy similar to the following:

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); }); } 

Your KO Tmpl, where you bind the href property of each table object with the a attribute of the href tag:

 <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>​ 
+3
source

Source: https://habr.com/ru/post/922535/


All Articles