您当前的位置: 首页 >  前端

寒冰屋

暂无认证

  • 1浏览

    0关注

    2286博文

    0收益

  • 0浏览

    0点赞

    0打赏

    0留言

私信
关注
热门博文

带有Upida/Jeneva的ASP.NET MVC单页应用程序(前端/AngularJS)

寒冰屋 发布时间:2019-10-24 14:33:38 ,浏览量:1

目录

介绍

背景

基本结构

JS控制器

HTML视图

查看容器

结论

参考

  • 下载源3.4 MB
  • 在Codeplex上下载最新版本和更多示例
  • 参见工作示例
介绍

在上一篇文章中,我演示了如何使用WebAPI和Jeneva.Net创建基于JSON的Web后端。在本文中,我将展示一些有关如何使用Angular.js创建单个页面前端的基本技巧。如果您不熟悉AngularJS的基础知识,请访问此YouTube频道。

背景

假设我们已经有一个工作的后端,它包含两个控制器——一个MVC控制器提供HTML视图,另一个WebAPI控制器为我们提供方便的REST JSON API。

public class ClientController : System.Web.Mvc.Controller
{
    public ActionResult List()
    {
        return this.View();
    }
 
    public ActionResult Create()
    {
        return this.View();
    }
 
    public ActionResult Edit()
    {
        return this.View();
    }
}
public class ClientController : System.Web.Http.ApiController
{
    public IClientService ClientService { get; set; }

    public Client GetById(int id)
    {
        return this.ClientService.GetById(id);
    }

    public IList GetAll()
    {
        return this.ClientService.GetAll();
    }

    public void Save(Client item)
    {
        this.ClientService.Save(item);
    }

    public void Update(Client item)
    {
        this.ClientService.Update(item);
    }

    [HttpPost]
    public void Delete(int id)
    {
        this.ClientService.Delete(id);
    }
}

两种控制器看起来都很简单且可行。请参考我以前的文章, 以了解如何创建后端。我的目标是为这两个控制器创建前端。前端必须是单页浏览器应用程序(SPA)。许多人认为SPA不是一种有用的技术,因为它不会产生指向不同页面的链接,并且SPA需要您付出大量的努力,因此不值得。我将向您展示,使用AngularJS,您可以像创建多页应用程序一样简单地创建SPA,并且多页应用程序的所有好处都将保留在SPA中。

基本结构

每个单页应用程序(SPA)的最重要部分是其结构。我们将有3个视图:“客户端列表”,“创建客户端”和“编辑客户端”。这实际上意味着,我们将有三个AngularJS这些视图控制器——clientListController.js,clientCreateController.js和clientEditController.js。“vendor”文件夹包含所有第三方库。我们也有自定义过滤器。通常,这种结构还具有“指令 ”和“服务 ”文件夹,但是在这个简单的SPA中,我没有使用任何自定义指令和服务。

前端的基本部分是位于js文件夹根目录中的app.js文件。让我们分析其内容。

var myclients = myclients || {};
myclients.app = angular.module("myclients", ["ngRoute", "jenevamodule"]);
 
myclients.app.config(function ($routeProvider) {
    $routeProvider
        .when("/", {
            templateUrl: "client/list",
            controller: "clientListController"
        })
        .when("/client/list", {
            templateUrl: "client/list",
            controller: "clientListController"
        })
        .when("/client/create", {
            templateUrl: "client/create",
            controller: "clientCreateController"
        })
        .when("/client/edit/:id", {
            templateUrl: "client/edit",
            controller: "clientEditController"
        })
        .otherwise({
            templateUrl: "home/notfound"
        });
});
 
$jeneva.settings.baseUrl = "/api/";

在第一行中,我定义了应用程序的主名称空间。然后,使用AngularJS,创建主模块的实例。这是每个Angular应用程序的常见任务。并且此模块依赖于两个不同的模块:ngRoute 和jenevamodule,它们都是独立的可重复使用的angular模块。最有趣的部分是在中间部分。如您所见,我在这里定义了几个路由器。这实际上是任何前端的核心。简单地说——在这里,我告诉AngularJS-应该打开哪个js控制器和哪个视图,具体取决于浏览器中的URL。每时每刻,我的应用程序只有一个活动视图和控制器,这取决于在浏览器窗口中输入的URL。例如,如果我输入url:client/list,则client/list视图和clientListController将被主动加载。

app.js的最后一部分专用于Jeneva.Net。我使用它是因为它使我的应用程序更易于开发和支持。我告诉Jeneva,我的WebAPI控制器位于/api/子文件夹中。

JS控制器

现在,让我们看一下控制器。第一个是clientListController.js。

myclients.app.controller(
    "clientListController", ["$scope", "jeneva",
    function ($scope, jeneva) {
 
    $scope.clientRows = new Array();
 
    $scope.ClientRow = function (id) {
        this.id = id;
        this.name = null;
        this.lastname = null;
        this.age = null;
        this.logins = new Array();
    };
 
    $scope.loadClients = function() {
        jeneva.get("client/getall")
        .then(function (items) {
            angular.forEach(items, function (p, i) {
                var row = new $scope.ClientRow(p.id);
                row.name = p.name;
                row.lastname = p.lastname;
                row.age = p.age;
                angular.forEach(p.logins, function (q, j) {
                    row.logins.push(q.name);
                });
                $scope.clientRows.push(row);
            });
        });
    };

   $scope.onDelete = function (clientId) {
      jeneva.post("client/delete/" + clientId)
      .then(function () {
         $scope.loadClients();
      });
   };
 
    $scope.$on("$routeChangeSuccess", function () {
        jeneva.setScope($scope);
        $scope.loadClients();
    });
}]);

如您所见,我指的是在app.js文件的前两行中创建的myclients.app模块。我的控制器已命名为clientListController,并注入了2个变量:$scope和jeneva。在控制器主体中,我定义了数据库中的客户端列表$scope.clientRows,这是我的视图模型。该$scope.loadClients方法与后端进行交互,其jeneva使用服务来调用WebAPI控制器。我使用jeneva服务而不是直接使用angular($http)调用的原因是——如果后端失败,并且我在视图中的正确位置(基于jvPath验证器和jvErrorkey指令)显示错误消息,jeneva会自动进行管理。当我的WebAPI返回客户列表,我将其填充到$scope.clientRows字段中。

我的控制器的最后一部分是最重要的。我将处理程序附加到该$routeChangeSuccess事件。每当此控制器处于活动状态时,即每次用户导航到“客户端列表”视图时,都会触发此事件。就我而言,触发此事件时,将调用$scope.loadClients方法,并从后端提取数据。

其他控制器大致相同。它们注入了$location变量,用于在AngularJS SPA中的视图之间导航。例如,clientCreateController.js:

myclients.app.controller(
    "clientCreateController",
    ["$scope", "$location", "jeneva", function ($scope, $location, jeneva) {
 
    $scope.name = null;
    $scope.lastname = null;
    $scope.age = null;
    $scope.loginRows = new Array();
 
    $scope.LoginRow = function () {
        this.name = null;
        this.password = null;
        this.enabled = false;
    };
 
    $scope.onRemoveLoginClick = function (item) {
        var index = $scope.loginRows.indexOf(item);
        $scope.loginRows.splice(index, 1);
    };
 
    $scope.onAddLoginClick = function () {
        var row = new $scope.LoginRow();
        $scope.loginRows.push(row);
    };
 
    $scope.onSave = function () {
        var data = {};
        data.name = $scope.name;
        data.lastname = $scope.lastname;
        data.age = $scope.age;
        data.logins = new Array();
        angular.forEach($scope.loginRows, function (p, i) {
            var item = {};
            item.name = p.name;
            item.password = p.password;
            item.enabled = p.enabled;
            data.logins.push(item);
        });
        jeneva.post("client/save", data)
        .then(function () {
            $location.path("client/list");
        });
    };
 
    $scope.$on("$routeChangeSuccess", function () {
        $scope.onAddLoginClick();
    });
}]);

看一下$scope.onSave方法。当用户单击“客户端创建”视图的“保存”按钮时,它将触发。它将所有用户输入的数据收集到一个大数据变量中,并使用jeneva服务将其作为JSON发送到WebAPI控制器。如果成功保存数据,则将调用$location.path()方法,并且用户将再次导航到“客户端列表”视图。如果后端失败或后端验证失败,则jeneva服务将处理此问题,并且所有验证问题将显示在视图中的正确位置,具体取决于jeneva指令(本文后面,您将看到Jeneva如何处理这些失败)。

clientEditController.js以同样的方式工作,你可以看到它的源代码。

HTML视图

如您所知,只有三个视图——客户端列表,创建客户端和编辑客户端。如果您不熟悉AngularJS,请参考此youtube频道。让我们看一下“列表”视图。

NEW CLIENT
Clients




    
        ID
        NAME
        LASTNAME
        AGE
        LOGINS
        
    


    
        
        
        
        
        
            
关注
打赏
1665926880
查看更多评论
0.0483s