Ответ 1
Вы можете просто поместить javascript-выражение в ng-model
.
Я хочу заполнить форму динамическими вопросами (скрипка здесь):
<div ng-app ng-controller="QuestionController">
<ul ng-repeat="question in Questions">
<li>
<div>{{question.Text}}</div>
<select ng-model="Answers['{{question.Name}}']" ng-options="option for option in question.Options">
</select>
</li>
</ul>
<a ng-click="ShowAnswers()">Submit</a>
</div>
function QuestionController($scope) {
$scope.Answers = {};
$scope.Questions = [
{
"Text": "Gender?",
"Name": "GenderQuestion",
"Options": ["Male", "Female"]},
{
"Text": "Favorite color?",
"Name": "ColorQuestion",
"Options": ["Red", "Blue", "Green"]}
];
$scope.ShowAnswers = function()
{
alert($scope.Answers["GenderQuestion"]);
alert($scope.Answers["{{question.Name}}"]);
};
}
Все работает, за исключением того, что модель буквально отвечает [ "{{question.Name}}" ], а не на оцененные ответы [ "GenderQuestion" ]. Как установить динамическое имя этой модели?
Вы можете просто поместить javascript-выражение в ng-model
.
Вы можете использовать что-то вроде этого scopeValue[field]
, но если ваше поле находится в другом объекте, вам понадобится другое решение.
Чтобы решить все ситуации, вы можете использовать эту директиву:
this.app.directive('dynamicModel', ['$compile', '$parse', function ($compile, $parse) {
return {
restrict: 'A',
terminal: true,
priority: 100000,
link: function (scope, elem) {
var name = $parse(elem.attr('dynamic-model'))(scope);
elem.removeAttr('dynamic-model');
elem.attr('ng-model', name);
$compile(elem)(scope);
}
};
}]);
Пример Html:
<input dynamic-model="'scopeValue.' + field" type="text">
То, что я закончил, выглядит примерно так:
В контроллере:
link: function($scope, $element, $attr) {
$scope.scope = $scope; // or $scope.$parent, as needed
$scope.field = $attr.field = '_suffix';
$scope.subfield = $attr.sub_node;
...
поэтому в шаблонах я мог бы использовать полностью динамические имена, а не только под определенным жестко закодированным элементом (например, в вашем случае "Ответы" ):
<textarea ng-model="scope[field][subfield]"></textarea>
Надеюсь, что это поможет.
Чтобы сделать ответ, предоставленный @abourget более полным, значение поля scopeValue [field] в следующей строке кода может быть undefined. Это приведет к ошибке при настройке подполя:
<textarea ng-model="scopeValue[field][subfield]"></textarea>
Одним из способов решения этой проблемы является добавление атрибута ng-focus = "nullSafe (field)", поэтому ваш код будет выглядеть следующим образом:
<textarea ng-focus="nullSafe(field)" ng-model="scopeValue[field][subfield]"></textarea>
Затем вы определяете nullSafe (поле) в контроллере, как показано ниже:
$scope.nullSafe = function ( field ) {
if ( !$scope.scopeValue[field] ) {
$scope.scopeValue[field] = {};
}
};
Это гарантирует, что scopeValue [field] не undefined перед установкой любого значения в scopeValue [field] [subfield].
Примечание: вы не можете использовать ng-change = "nullSafe (field)" для достижения того же результата, потому что ng-change происходит после изменения ng-модели, что вызовет ошибку, если scopeValue [field] undefined.
Или вы можете использовать
<select [(ngModel)]="Answers[''+question.Name+'']" ng-options="option for option in question.Options">
</select>