角 js 从默认值初始化 n- 模型

假设您有一个从数据库加载值的表单。如何初始化 n- 模型?

例如:

<input name="card[description]" ng-model="card.description" value="Visa-4242">

在我的控制器中,$scope.card 最初是未定义的?

$scope.card = {
description: $('myinput').val()
}
227601 次浏览

这是一个常见的错误,在新的角度应用。如果可以避免的话,您不希望将您的值写入服务器上的 HTML 中。如果事实上,如果您可以摆脱让您的服务器完全呈现 HTML,那就更好了。

理想情况下,您希望发送您的角 HTML 模板,然后通过 $http 在 JSON 中下拉您的值,并将它们放在您的作用域中。

因此,如果可能的话,请这样做:

app.controller('MyController', function($scope, $http) {
$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});
});


<input type="text" ng-model="card.description" />

If you absolutely MUST render your values into your HTML from your server, you could put them in a global variable and access them with $window:

In the header of your page you'd write out:

<head>
<script>
window.card = { description: 'foo' };
</script>
</head>

And then in your controller you'd get it like so:

app.controller('MyController', function($scope, $window) {
$scope.card = $window.card;
});

希望能帮上忙。

如果你不能按照@blesh 的建议重写你的应用程序(使用 $http 或 $resource 下拉 JSON 数据并填充 $scope) ,你可以使用 (咒语)代替:

<input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">

参见 当使用 n- 模型时,输入文本框上的 AngularJS-Value 属性是否被忽略?

我尝试了@Mark Rajcok 的建议,它适用于字符串值(Visa-4242)。 请参阅此 小提琴

From the fiddle:

同样的事情是在小提琴可以做的使用 ng-repeat,这是每个人都可以推荐。但是在阅读了@Mark Rajcok 给出的答案之后,我只是想对一个具有配置文件数组的表单尝试同样的方法。 在控制器中有 $scope.profile = [{} ,{}] ; 代码之前,一切都很顺利。如果我删除这个代码,我得到错误。 但是在正常情况下,我不能打印 $scope.profiles = [{},{}];,因为我打印或回显 html 从服务器。 是否有可能像@Mark Rajcok 对字符串值(如 <input name="card[description]" ng-model="card.description" ng-init="card.description='Visa-4242'">)所做的那样执行上述操作,而不必从服务器回显 JavaScript 部分。

This is an obviously lacking, but easily added fix for AngularJS. Just write a quick directive to set the model value from the input field.

<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);
}
]
};
});

刚刚为 Ryan Montgomery“ fix”添加了对选择元素的支持

<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)
}]
}

});

恕我直言,最好的解决方案是@Kevin Stone 指令,但是我不得不升级它以适应各种条件(比如选择,文本区域) ,而且这个方法肯定有效:

    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);
}
}
}
}
});

正如其他人指出的那样,在视图上初始化数据并不是一个好的实践。 但是,建议在 Controller 上初始化数据(参见 http://docs.angularjs.org/guide/controller)

这样你才能写作

<input name="card[description]" ng-model="card.description">

and

$scope.card = { description: 'Visa-4242' };


$http.get('/getCardInfo.php', function(data) {
$scope.card = data;
});

这样,视图不包含数据,控制器在加载实际值时初始化该值。

如果你喜欢凯文 · 斯通上面的 https://stackoverflow.com/a/17823590/584761 考虑一种更简单的方法,为特定的标记(如“ input”)编写指令。

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);
}
}
}; });

如果使用这种方法,就不必担心在每个标记中添加 n- 首字母。它自动将模型的值设置为标记的 value 属性。如果不设置 value 属性,它将默认为空字符串。

如果在 URL 中有初始值(如 mypage/id) ,那么在角度 JS 的控制器中,可以使用 location.pathname查找 id 并将其分配给所需的模型。

以下是一种以服务器为中心的方法:

<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"
}

并通过您选择的服务器端技术将其放入您的页面

也可以在 HTML 代码中使用: ng-init="card.description = 12345"

It is not recommended by Angular, and as mentioned above you should use exclusively your controller.

但它确实有效:)

您可以使用自定义指令(支持 textarea、 select、单选和复选框) ,查看这篇博客文章 https://glaucocustodio.github.io/2014/10/20/init-ng-model-from-form-fields-attributes/

This one is a more generic version of the ideas mentioned above... 它只是检查模型中是否有任何值,如果没有,它就将值设置为模型。

约翰逊:

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 (usage example):

<select class="form-control"
ng-options="v for (i, v) in compressionMethods"
ng-model="action.parameters.Method"
default-value="'LZMA2'"></select>

我有一个简单的方法,因为我有一些沉重的验证和面具在我的形式。因此,我使用 jquery 再次获取我的值,并将事件“ change”激发为验证:

$('#myidelement').val('123');
$('#myidelement').trigger( "change");