将 AngularJS 绑定到 MVC ViewModel 属性

Binding AngularJS to MVC ViewModel properties

我开始学习 AngularJS 并尝试在 MVC 应用程序中使用它。我有一个 MVC ViewModel,它具有从数据库中填充的属性,并且我有一个绑定到此 ViewModel 的视图。所以在普通的 MVC 视图中,我可以做类似 @Model.UserBaseViewModel.FirstName 的事情。我想做的是让我的数据来自 ViewModel 并通过 ViewModel 保存,但我希望 AngularJS 像这样编辑和显示数据:

代码

app.controller('ConsultantPersonalInformationController', function($scope, $filter, $http) {
    $scope.user = {
        id: 1,
        firstName: @Model.UserBaseViewModel.FirstName,
        lastName: @Model.UserBaseViewModel.LastName
    };

    //other code is here
});

我不确定是否有办法做到这一点。 AngularJS 是否需要获取并保存正在显示的数据,或者我可以改用 MVC ViewModel 属性。

如您所料,这不是解决问题的方法。

AngularJS 有一个 SPA 架构,这意味着你加载你的第一页一次,然后你切换状态而不去服务器(除了获取模板 HTML 如果需要,或者明确指定使用ajax 请求)。写入 firstName: @Model.UserBaseViewModel.FirstName 没有任何意义,因为 @Model.. 行是在页面下载到客户端之前在服务器端进行评估的,并且由于您不断切换状态(或者您可以,无论如何)数据是不可用。

您需要切换到 RESTful 心态,向服务器发送请求,return 您需要的数据,然后填充该数据。因此,假设在进入状态 A 后,您需要去获取 user 数据,您将拥有类似于:

的代码
app.controller('ConsultantPersonalInformationController', function($scope, $filter, $http, userService) {

    userService.getUserData().then(function(res) { 
        $scope.user = {
            id: 1,
            firstName: res.FirstName,
            lastName: res.LastName
        };
    }

    //other code is here
});

getUserData 是一个异步操作,它将 return 一个承诺(阅读更多内容 here),一旦准备就绪,您将拥有服务器 returned 数据在 res 变量中是回调函数。

您需要先将 MVC 模型传递给页面并将其插入到 JS 包装器中。从那里你可以在你的控制器中引用它。请记住在您的页面中将 JS 包装器放在您的控制器范围内。 这是一个简单的例子

从 MVC 控制器创建一些数据并将其作为模型传递给页面

public ViewResult Index()
        {
            object model = bootStrapData();
            return View("Index", model);
        }

private string bootStrapData()
        {
            string someObject = string.Empty;
            var c = //dosomething
            someObject= c.ToString();

            //even though one value we will follow the Json pattern and camelCase the return
            var settings = new JsonSerializerSettings { ContractResolver = new CamelCasePropertyNamesContractResolver() };
            return JsonConvert.SerializeObject(isReportWriter, Formatting.None, settings);
        }

在您的视图中将模型设置为 javascript 变量

<!-- Bootstrapping controller from ASP.MVC Controller-->
<script type="text/javascript">
    app.factory('bootStrappedData', function() {
        return   { someObject: @Html.Raw(Model) };
    });
</script>

然后在您的控制器中,您可以将引用设置为 $scoped 对象

//bootstrapping from MVC controller
    $scope.myObject = (bootStrappedData.someObject === "True");    

这里我明确地获取了一个布尔值来处理 ng-showng-hide,但如果需要,您可以传入字符串或任何其他对象

最后记得在你的控制器中设置你在页面中创建的服务的依赖关系,否则它不会被定义

app.controller('myController', ['$scope', 'bootStrappedData' function(,scope, bootStrappedData)
...
]);

谢谢大家。 我现在意识到我不能按照设计混合使用 MVC 和 AngularJS。就我而言,我可以只使用 MVC 而不是 AngularJS,但我想充分利用两者并开始学习 AngularJS,所以这就是我所做的。 在 MVC 端,我填充了我的 ViewModel 并为该 ViewModel 创建了一个强类型视图。在视图中,我这样引用我的 ViewModel:

@model Project_X_01202015_Web.ViewModel.ConsultantViewModel

比起我正常创建 AngularJS 零件,除了以下情况:

$scope.user = { id: 1, isVerifiedUser: '@Model.UserBaseViewModel.IsVerifiedUser', firstName: '@Model.UserBaseViewModel.FirstName', middleName: '@Model.UserBaseViewModel.MiddleName', lastName: '@Model.UserBaseViewModel.LastName', email: '@Model.UserBaseViewModel.Email', address: '@Model.UserBaseViewModel.Address', address1: '@Model.UserBaseViewModel.Address1', phoneNumber: '@Model.UserBaseViewModel.PhoneNumber', cell: '@Model.UserBaseViewModel.PhoneNumber1', city: '@Model.UserBaseViewModel.CityName', postalCode: '@Model.UserBaseViewModel.PostalCode', state: '@Model.UserBaseViewModel.StateName' };

我可以在视图上更改 $scope.user 中的属性值,当我需要更新从数据库填充的 ViewModel 对象时,我必须先用这些值更新我的数据库,然后而不是重新填充我的 ViewModel 并将其返回给视图,或者只是更新当前的 ViewModel 实例并刷新页面。但是我没有刷新页面,而是更新了视图并向 MVC 控制器发送了一个调用来更新数据库。通过这种方式更新视图,每当用户刷新页面时,实际数据都来自数据库,UI 上的信息不会改变。
我可以像这样更新 $scope.user 值:$scope.user.city = "Huntsville";,当我需要将任何信息发送回 MVC 控制器时,我这样做了:url: '/Consultant/SaveConsultantInformation', async: 'false', type: 'POST', dataType: 'json', data: { user: $scope.user }, 在我的 post 调用中。 AngularJs post/get 确实有一些问题,无法从成功更新 $scope.user 值: post/get 和 [ 的函数(结果){} =23=] 比简单的 $('#verifyMeButton').hide(); 更涉及基本用途;但我为此做了一个非 AngularJS 的解决方法。总而言之,我认为 AngularJS 也非常适合在 UI 中四处走动,我将继续使用它。