假设您有一个从数据库加载值的表单。你如何初始化 ng-model?
例子:
<input name="card[description]" ng-model="card.description" value="Visa-4242">
在我的控制器中, $scope.card 最初是未定义的。除了做这样的事情,还有什么办法吗?
$scope.card = {
description: $('myinput').val()
}
假设您有一个从数据库加载值的表单。你如何初始化 ng-model?
例子:
<input name="card[description]" ng-model="card.description" value="Visa-4242">
在我的控制器中, $scope.card 最初是未定义的。除了做这样的事情,还有什么办法吗?
$scope.card = {
description: $('myinput').val()
}
如果您无法按照@blesh 的建议重新设计您的应用程序(使用 $http 或 $resource 下拉 JSON 数据并填充 $scope),您可以改用ng-init:
<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
这是新 Angular 应用程序中的常见错误。如果可以避免的话,您不想将值写入服务器上的 HTML。事实上,如果您可以避免让服务器完全呈现 HTML,那就更好了。
理想情况下,您希望发送您的 Angular HTML 模板,然后通过 JSON 中的 $http 提取您的值并将它们放入您的范围。
因此,如果可能,请执行以下操作:
app.controller('MyController', function($scope, $http) {
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
});
<input type="text" ng-model="card.description" />
如果您绝对必须将您的值从您的服务器呈现到您的 HTML 中,您可以将它们放在一个全局变量中并使用 $window 访问它们:
在页面的标题中,您会写出:
<head>
<script>
window.card = { description: 'foo' };
</script>
</head>
然后在你的控制器中你会得到它:
app.controller('MyController', function($scope, $window) {
$scope.card = $window.card;
});
我希望这会有所帮助。
这是 AngularJS 的一个明显缺乏但很容易添加的修复。只需编写一个快速指令即可从输入字段设置模型值。
<input name="card[description]" value="Visa-4242" ng-model="card.description" ng-initial>
这是我的版本:
var app = angular.module('forms', []);
app.directive('ngInitial', function() {
return {
restrict: 'A',
controller: [
'$scope', '$element', '$attrs', '$parse', function($scope, $element, $attrs, $parse) {
var getter, setter, val;
val = $attrs.ngInitial || $attrs.value;
getter = $parse($attrs.ngModel);
setter = getter.assign;
setter($scope, val);
}
]
};
});
恕我直言,最好的解决方案是@Kevin Stone 指令,但我必须升级它才能在各种条件下工作(fe select、textarea),而这个肯定可以工作:
angular.module('app').directive('ngInitial', function($parse) {
return {
restrict: "A",
compile: function($element, $attrs) {
var initialValue = $attrs.value || $element.val();
return {
pre: function($scope, $element, $attrs) {
$parse($attrs.ngModel).assign($scope, initialValue);
}
}
}
}
});
您可以使用自定义指令(支持 textarea、select、radio 和 checkbox),查看这篇博文https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-字段属性/。
您还可以在 HTML 代码中使用:
ng-init="card.description = 12345"
Angular 不建议这样做,如上所述,您应该专门使用您的控制器。
但它有效:)
我有一个简单的方法,因为我的表单中有一些繁重的验证和掩码。因此,我使用 jquery 再次获取我的值并将事件“更改”触发到验证:
$('#myidelement').val('123');
$('#myidelement').trigger( "change");
正如其他人指出的那样,在视图上初始化数据并不是一个好习惯。但是,建议在 Controller 上初始化数据。(见http://docs.angularjs.org/guide/controller)
所以你可以写
<input name="card[description]" ng-model="card.description">
和
$scope.card = { description: 'Visa-4242' };
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
这样视图不包含数据,并且控制器在加载实际值时初始化值。
如果您喜欢 Kevin Stone 在https://stackoverflow.com/a/17823590/584761上的方法,请 考虑通过为特定标签(例如“输入”)编写指令来更简单的方法。
app.directive('input', function ($parse) {
return {
restrict: 'E',
require: '?ngModel',
link: function (scope, element, attrs) {
if (attrs.ngModel) {
val = attrs.value || element.text();
$parse(attrs.ngModel).assign(scope, val);
}
}
}; });
如果你走这条路,你就不必担心将 ng-initial 添加到每个标签。它自动将模型的值设置为标签的 value 属性。如果您不设置 value 属性,它将默认为空字符串。
这是一种以服务器为中心的方法:
<html ng-app="project">
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.2.23/angular.min.js"></script>
<script>
// Create your module
var dependencies = [];
var app = angular.module('project', dependencies);
// Create a 'defaults' service
app.value("defaults", /* your server-side JSON here */);
// Create a controller that uses the service
app.controller('PageController', function(defaults, $scope) {
// Populate your model with the service
$scope.card = defaults;
});
</script>
<body>
<div ng-controller="PageController">
<!-- Bind with the standard ng-model approach -->
<input type="text" ng-model="card.description">
</div>
</body>
</html>
除了$provide.value注册了一个包含您的默认值的服务之外,这与此问题上更流行的答案的基本思想相同。
所以,在服务器上,你可以有类似的东西:
{
description: "Visa-4242"
}
并通过您选择的服务器端技术将其放入您的页面。这是一个要点:https ://gist.github.com/exclsr/c8c391d16319b2d31a43
这个是上面提到的想法的一个更通用的版本......它只是检查模型中是否有任何值,如果没有,它将值设置给模型。
JS:
function defaultValueDirective() {
return {
restrict: 'A',
controller: [
'$scope', '$attrs', '$parse',
function ($scope, $attrs, $parse) {
var getter = $parse($attrs.ngModel);
var setter = getter.assign;
var value = getter();
if (value === undefined || value === null) {
var defaultValueGetter = $parse($attrs.defaultValue);
setter($scope, defaultValueGetter());
}
}
]
}
}
HTML(使用示例):
<select class="form-control"
ng-options="v for (i, v) in compressionMethods"
ng-model="action.parameters.Method"
default-value="'LZMA2'"></select>
我尝试了@Mark Rajcok 的建议。它适用于字符串值(Visa-4242)。请参考这个小提琴。
从小提琴:
在小提琴中完成的同样的事情可以使用 来完成ng-repeat
,每个人都可以推荐。但是在阅读了@Mark Rajcok 给出的答案之后,我只是想尝试对具有配置文件数组的表单进行相同的操作。在我拥有 $scope.profiles = [{},{}]; 之前一切正常 控制器中的代码。如果我删除此代码,我会收到错误消息。但在正常情况下$scope.profiles = [{},{}];
,当我从服务器打印或回显 html 时,我无法打印。是否有可能以与@Mark Rajcok 对字符串值类似的方式执行上述操作<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">
,而不必从服务器回显 JavaScript 部分。
刚刚向 Ryan Montgomery “修复”添加了对选择元素的支持
<select class="input-control" ng-model="regCompModel.numberOfEmployeeId" ng-initial>
<option value="1af38656-a752-4a98-a827-004a0767a52d"> More than 500</option>
<option value="233a2783-db42-4fdb-b191-0f97d2d9fd43"> Between 250 and 500</option>
<option value="2bab0669-550c-4555-ae9f-1fdafdb872e5"> Between 100 and 250</option>
<option value="d471e43b-196c-46e0-9b32-21e24e5469b4"> Between 50 and 100</option>
<option value="ccdad63f-69be-449f-8b2c-25f844dd19c1"> Between 20 and 50</option>
<option value="e00637a2-e3e8-4883-9e11-94e58af6e4b7" selected> Less then 20</option>
</select>
app.directive('ngInitial', function () {
return {
restrict: 'A',
controller: ['$scope', '$element', '$attrs', '$parse', function ($scope, $element, $attrs, $parse) {
val = $attrs.sbInitial || $attrs.value || $element.val() || $element.text()
getter = $parse($attrs.ngModel)
setter = getter.assign
setter($scope, val)
}]
}
});
如果您在 URL 中有 init 值mypage/id
,那么在 Angular JS 的控制器中,您可以使用location.pathname
它来查找 id 并将其分配给您想要的模型。