Angularjs 使用MVC Html.TextBoxFOr绑定角度模型

Angularjs 使用MVC Html.TextBoxFOr绑定角度模型,angularjs,asp.net-mvc-5,Angularjs,Asp.net Mvc 5,我有与ASP.net MVC5模型相关的控件 @Html.TextBoxFor(model => model.OriginLocation.City, new { @class = "form-control", data_ng_model = "address1.City", test_change = "" }) 因此,当页面加载文本框的值时,输入是绑定的,并且应该显示来自带有Razor绑定控件的服务的值,后者我可以操作该值,从而更改该控件的角度模型。 我的文本框是空的。 我可以在

我有与ASP.net MVC5模型相关的控件

 @Html.TextBoxFor(model => model.OriginLocation.City, new { @class = "form-control", data_ng_model = "address1.City", test_change = "" })
因此,当页面加载文本框的值时,输入是绑定的,并且应该显示来自带有Razor绑定控件的服务的值,后者我可以操作该值,从而更改该控件的角度模型。 我的文本框是空的。 我可以在查看源代码时看到该值,但未显示该值

<input class="form-control ng-pristine ng-valid" data-ng-model="address1.City" data-val="true" data-val-length="The field City must be a string with a maximum length of 50." data-val-length-max="50" id="OriginLocation_City" name="OriginLocation.City" test-change="" type="text" value="Manheim">

ngModel
优先于最初设置的值(因为模型不存在,所以将值设置为“”)。看看这里

但是您可以使用
ngInit
…指定一个值

这意味着您可以在生成文本框时使用
ngInit

@Html.TextBoxFor(model => model.OriginLocation.City,
    new { @class = "form-control", 
         data_ng_model = "address1.City", 
         test_change = "",
         data_ng_init = string.Format("address1.City = '{0}'", Model.OriginLocation.City.Replace("'", @"\'"))  })

Angular将用其自身模型中的值替换文本框的内容,这意味着您需要填充Angular模型。这可以通过将MVC模型(或其中的一部分)序列化到角度模型中来快速实现:

app.controller("TestController", function($scope) {
    $scope.person = @Html.Raw(JsonConvert.SerializeObject(Model.Person));
});
然后可以在视图中呈现MVC控件,如下所示:

@Html.TextBoxFor(x => x.Person.Name, new { ng_model = "person.Name" })

考虑到@Alan的答案,我找到了一种“有点”干净的方法。这就是我在使用Angular.js创建ASP MVC项目时使用的解决方案

我没有在Angular控制器内序列化模型(这需要在Razor模板内声明控制器),而是在每个Razor模板的全局变量中序列化它,如:

<script>
    //Add the namespace you want to not poluate the global namespace
    window.Model = @Html.Raw(JsonConvert.SerializeObject(Model))
</script>
在那之后,在我的控制器中,我只是做一些

app.controller("TestController", function($scope) {
    $scope.model = window.Model;
    //My other stuff...
});

此外,角度模型始终具有与ASP MVC模型相同的属性。

解决此生命周期问题的一个干净方法是为输入的“value”属性编写指令

首先,您可以使用基本Razor语法在yout输入元素中简单地编写Razor的模型值


您还可以显示您的脚本吗?.js?我没有在js中设置任何内容,但现在尝试获取控件w jquery的值,这不是首选项,但仍然没有。这是片段app.controller('LocationCtrl',[“$scope”,function($scope){$scope.address1={Label:'address1',address1:$(“#OriginLocation.address1”).val(),城市:$(“#OriginLocation.City”).val(),State:$(#OriginLocation.State”).val(),PostalCode:$(#OriginLocation.PostalCode”).val(),};我的意思是,你能在你的帖子中展示你的js吗,而不是在评论中。原始帖子中没有足够的信息让任何人给出任何答案。我尝试了ng_init,它确实有效,但这是最好的也是唯一的方法吗?我认为这离理想还很远。你想用Angular做什么?就个人而言,我要么坚持使用ng_initg MVC/Razor使用一点jQuery,或者让Angular呈现页面并通过服务获取/保存数据。我试图做的是从服务器加载数据,以便使用MVC/Razor呈现,但后者在表单上有交互时使用Angular进行双向数据绑定,例如,提前键入地址,修改1控件的值等其他事情会发生更改其他人的值。当需要提交表单时,它是通过表单发布到MVC控制器的?我想不出更好的方法来做到这一点。在这个设计中有很多摩擦,因为你必须做很多工作才能将数据从MVC传输到Angular。你可以看看这个答案,看看如何将你的C#模型作为JSON放在JavaScript中,我不知道这是否会更好……我想如果你打算在Angular方面做更多的工作,比如添加autocomplete,那么你无论如何都应该编写REST服务来支持这些。你不妨将整个过程转换为带有REST API的SPA。如果你使用
@Html.Raw()
方法要填充您的模型,您需要从
.js
文件中提取控制器的代码,并将其直接放入页面模板中,这是一种很糟糕的模式,因为您的所有js都应该在同一个位置,而不是在整个解决方案中分发。是的,我完全同意。我得出了结论(经验丰富)将两个独立的MVC框架混搭在一起并不好。Angular over WebAPI效果很好,是一个更好的解决方案。我真的很喜欢Angular,但我不明白为什么这个框架必须优先考虑模型值的内容,而不是从输入中获取它的值。这不是一个真正的双向绑定框架如果加载页面时它没有得到HTML的值,或者至少给我们在控制器中设置配置的能力来实现这一点,那么这就是我的拙见。您现在是否使用与Angular不同的方法来完成这类过程?不,我倾向于使用Angular与静态HTML模板一起使用,并使用WebAPI服务调用来下拉数据。I d我不认为有一种优雅的方法可以使用输入字段中的数据对其作用域进行角度预加载。
public class Classroom {
    public string Title {get;set;}

    [ScriptIgnore]
    //Students could be associated to classroom, and that classroom has  
    //  students etc. If you want those properties, create a new object in a 
    //  PageView withtout circular references
    public List<Students> Students {get;set;}
}
app.controller("TestController", function($scope) {
    $scope.model = window.Model;
    //My other stuff...
});