Update-Package knockoutjs Update-Package jQuery
, and install: Install-Package Breeze.WebApi Install-Package datajs
. <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width" /> <title>@ViewBag.Title</title> @Styles.Render("~/Content/css") @Styles.Render("~/Content/dx") @Styles.Render("~/Content/layouts") @Scripts.Render("~/bundles/modernizr") </head> <body> @Html.Partial("NavbarLayout") @RenderBody() @Scripts.Render("~/bundles/jquery") @RenderSection("scripts", required: false) </body> </html>
// bundles.Add(new ScriptBundle("~/bundles/knockout").Include( "~/Scripts/knockout-{version}.js")); bundles.Add(new ScriptBundle("~/bundles/breeze").Include( "~/Scripts/q.js", "~/Scripts/datajs-{version}.js", "~/Scripts/breeze.debug.js" )); bundles.Add(new ScriptBundle("~/bundles/dx").Include( "~/Scripts/dx.phonejs.js", "~/Scripts/globalize" )); bundles.Add(new ScriptBundle("~/bundles/app").Include( "~/Scripts/App/app.init.js", "~/Scripts/App/app.viewmodel.js", "~/Scripts/App/NavbarLayout.js" )); bundles.Add(new StyleBundle("~/Content/dx").Include("~/Content/dx/dx.*")); bundles.Add(new StyleBundle("~/Content/layouts").Include("~/Content/layouts/NavbarLayout.css"));
public class Route { public int RouteID { get; set; } [Required] [StringLength(30)] public string RouteName { get; set; } } public class Customer { public int CustomerID { get; set; } [Required] [StringLength(50)] public string CustomerName { get; set; } [StringLength(150)] public string Address { get; set; } public string Comment { get; set; } [ForeignKey("Route")] public int RouteID { get; set; } virtual public Route Route { get; set; } }
public class RoutesController : EntitySetController<Route, int> { private MSalesContext db = new MSalesContext(); public override IQueryable<Route> Get() { return db.Routes; ; } protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); } } public class CustomersController : EntitySetController<Customer, int> { private MSalesContext db = new MSalesContext(); public override IQueryable<Customer> Get() { return db.Customers; ; } protected override Customer GetEntityByKey(int key) { return db.Customers.FirstOrDefault(p => p.CustomerID == key); } protected override void Dispose(bool disposing) { db.Dispose(); base.Dispose(disposing); } }
public static class WebApiConfig { public static void Register(HttpConfiguration config) { config.Routes.MapODataRoute("odata", "odata", GetEdmModel()); config.Routes.MapHttpRoute( name: "DefaultApi", routeTemplate: "api/{controller}/{id}", defaults: new { id = RouteParameter.Optional } ); config.EnableQuerySupport(); config.EnableSystemDiagnosticsTracing(); } public static IEdmModel GetEdmModel() { ODataModelBuilder builder = new ODataConventionModelBuilder(); builder.EntitySet<Route>("Routes"); builder.EntitySet<Customer>("Customers"); builder.Namespace = "MSales.Models"; return builder.GetEdmModel(); } }
builder.Namespace = "MSales.Models";
required for the breeze and datajs libraries to work. window.MyApp = {}; $(function () { MyApp.app = new DevExpress.framework.html.HtmlApplication({ namespace: MyApp, defaultLayout: "navbar", navigation: [ { title: "Routes", action: "#route", icon: "home" }, { title: "About", action: "#about", icon: "info" } ] }); MyApp.app.router.register(":view/:id", { view: "route", id: 0 }); MyApp.app.navigate(); var serverAddress = "/odata/"; breeze.config.initializeAdapterInstances({ dataService: "OData" }); MyApp.manager = new breeze.EntityManager(serverAddress); });
<div data-options="dxView : { name: 'route', title: 'Routes' } " > <div class="route-view" data-options="dxContent : { targetPlaceholder: 'content' } " > <div data-bind="dxList: { dataSource: dataSource }"> <div data-options="dxTemplate : { name: 'item' }" data-bind="text: RouteName, dxAction: '#customers/{RouteID}'"/> </div> </div> </div>
MyApp.route = function (params) { var viewModel = { dataSource: { load: function (loadOptions) { if (loadOptions.refresh) { var deferred = new $.Deferred(); var query = breeze.EntityQuery.from("Routes").orderBy("RouteID"); MyApp.manager.executeQuery(query, function (result) { deferred.resolve(result.results); }); return deferred; } } } } return viewModel; };
<div data-options="dxView : { name: 'about', title: 'About' } "> <div data-options="dxContent : { targetPlaceholder: 'content' } "> <div data-bind="dxScrollView: {}"> <p style="padding: 5px">This is my first SPA application.</p> </div> </div> </div>
dxAction: '#customers/{RouteID}'
event is hung on the list item, where, according to the specified navigation, '#customers
is the View called, and RouteID
is the parameter passed to this View: <div data-options="dxView : { name: 'customers', title: 'Customers' } " > <div data-bind="dxCommand: { title: 'Search', placeholder: 'Search...', location: 'create', icon: 'find', action: find }" ></div> <div data-options="dxContent : { targetPlaceholder: 'content' } " > <div data-bind="dxTextbox: { mode: 'search', value: searchString, visible: showSearch, valueUpdateEvent: 'search change keyup' }"></div> <div data-bind="dxList: { dataSource: dataSource }"> <div data-options="dxTemplate : { name: 'item' } " data-bind="text: name, dxAction: '#customer-details/{id}'"/> </div> </div> </div>
MyApp.customers = function (params) { var skip = 0; var PAGE_SIZE = 10; var viewModel = { routeId: params.id, searchString: ko.observable(''), showSearch: ko.observable(false), find: function () { viewModel.showSearch(!viewModel.showSearch()); viewModel.searchString(''); }, dataSource: { changed: new $.Callbacks(), load: function (loadOptions) { if (loadOptions.refresh) { skip = 0; } var deferred = new $.Deferred(); var query = breeze.EntityQuery.from("Customers") .where("CustomerName", "substringof", viewModel.searchString()) .where("RouteID", "eq", viewModel.routeId) .skip(skip) .take(PAGE_SIZE) .orderBy("CustomerID"); MyApp.manager.executeQuery(query, function (result) { skip += PAGE_SIZE; console.log(result); var mapped = $.map(result.results, function (data) { return { name: data.CustomerName, id: data.CustomerID } }); deferred.resolve(mapped); }); return deferred; } } }; ko.computed(function () { return viewModel.searchString(); }).extend({ throttle: 500 }).subscribe(function () { viewModel.dataSource.changed.fire(); }); return viewModel; };
<div data-options="dxView : { name: 'customer-details', title: 'Product' } " > <div data-options="dxContent : { targetPlaceholder: 'content' } " > <div class="dx-fieldset"> <div class="dx-field"> <div class="dx-field-label">Id: </div> <div class="dx-field-value" data-bind="text: id"></div> </div> <div class="dx-field"> <div class="dx-field-label">Name: </div> <div class="dx-field-value" data-bind="text: name"></div> </div> <div class="dx-field"> <div class="dx-field-label">Address: </div> <div class="dx-field-value" data-bind="text: address"></div> </div> <div class="dx-field"> <div class="dx-field-label">Comment: </div> <div class="dx-field-value" data-bind="text: comment"></div> </div> </div> </div> </div>
MyApp['customer-details'] = function (params) { var viewModel = { id: parseInt(params.id), name: ko.observable(''), address: ko.observable(''), comment:ko.observable('') }; var data = MyApp.manager.getEntityByKey("Customer", viewModel.id); console.log(data); viewModel.name(data.CustomerName()); viewModel.address(data.Address()); viewModel.comment(data.Comment()); return viewModel; };
Source: https://habr.com/ru/post/185316/
All Articles