Reputation: 324
In my application I'm returning the view below which uses this TestViewModel.
public class TestViewModel
{
public List<string> Tests { get; set; }
}
View:
@model AdminSite.Models.TestsViewModel
@{
ViewBag.Title = "Tests";
}
<hgroup class="title">
<h1>@ViewBag.Title</h1>
</hgroup>
<!doctype html>
<html>
<head>
<script src="~/Scripts/Angular/angular.min.js"></script>
<script src="~/Scripts/Angular/Tests.js"></script>
</head>
<body>
<div ng-app="testsTable">
<div ng-controller="TableController">
<table my-table options="options"></table>
</div>
</div>
</body>
</html>
As you can see I'm using AngularJS to create a DataTable, what I would like though is that instead of the table data "aaData" being hardcoded I want it to be from TestViewModel model.
var app = angular.module('testsTable', []);
app.directive('myTable', function () {
return {
restrict: 'A',
link: function (scope, element, attrs, controller) {
var dataTable = element.dataTable(scope.options);
},
scope: {
options: "="
}
};
});
app.controller('TableController', ['$scope', function ($scope) {
$scope.options = {
aoColumns: [
{
"sTitle": "Col 1",
},
{
"sTitle": "Col 2"
},
{
"sTitle": "Col 3"
}
],
aoColumnDefs: [{
"bSortable": true,
}],
bJQueryUI: true,
bDestroy: true,
aaData: [
["A", "B", "C"],
["A", "B", "C"],
]
};
}]);
I think I may have to create another directive to bind the model e.g
<table my-table options="options" model-data="@Model.Tests"></table>
but I'm not really sure how Angular directives work exactly, how I would write said directive & how it binds it to the scope
Upvotes: 1
Views: 8215
Reputation: 834
Since you're working with angular, take advantage of angular configuration:
<script>
(function () {
angular.module('app').value('mydata', {
propOne: '@Url.Action("Index", "Dirty", null)',
propTwo: angular.fromJson('@Html.Raw(Model.Addresses)')
// more properties here
});
})();
</script>
Then you can inject and use 'mydata' anywhere within your angular application
EDIT:
You can create an extension method that serializes your model to JSON, then Html.Raw
won't give you an error, as long as the parameter you provide is not null.
public static class ObjectExtensions
{
public static string SerializeObject(this object obj) {
return JsonConvert.SerializeObject(
obj,
new JsonSerializerSettings {
ContractResolver = new CamelCasePropertyNamesContractResolver()
});
}
}
Then do:
@using [static extension class namespace here];
...
angular.fromJson('@Html.Raw(Model.Addresses.SerializeObject())')
Upvotes: 0
Reputation: 324
So...Setting aaData using {{options.aaData=JSON.parse('@Html.Raw(@Model.Tests)');""}}
was working but I had nothing monitoring the change meaning the table wasn't being redrawn with the new information.
to track changes I added a watch in my directive, this monitors aaData for changes then updates the table as necessary.
scope.$watch('options.aaData', handleUpdate, true);
function handleUpdate(newData) {
var data = newData || null;
if (data) {
dataTable.fnClearTable();
dataTable.fnAddData(newData);
}
}
my real solution looks a little different now as I am using dataTables ajax call to pull down my json data then setting the dataSrc with the result. Using the in-built ajax calls means I can remove the directive watch as datatables handles this for me.
One final note, if you've found yourself here while figuring out how to mix angularJS & dataTables then this fiddle has helped me a lot. http://jsfiddle.net/TNy3w/2/
Upvotes: 0
Reputation: 5545
Your question is answered here
You could directly inject the values into JavaScript:
//View.cshtml
<script type="text/javascript">
var arrayOfArrays = JSON.parse('@Html.Raw(Model.Addresses)');
</script>
See JSON.parse
, Html.Raw
Alternatively you can get the values via Ajax:
public ActionResult GetValues()
{
// logic
// Edit you don't need to serialize it just return the object
return Json(new { Addresses: lAddressGeocodeModel });
}
<script type="text/javascript">
$(function() {
$.ajax({
type: 'POST',
url: '@Url.Action("GetValues")',
success: function(result) {
// do something with result
}
});
});
</script>
See jQuery.ajax
Upvotes: 0