Chcę wypełnić formularz kilkoma dynamicznymi pytaniami (skrzypce tutaj ):
<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}}"]);
};
}
Wszystko działa, z wyjątkiem tego, że model to dosłownie Answers ["{{question.Name}}"], zamiast ocenionych odpowiedzi ["GenderQuestion"]. Jak mogę dynamicznie ustawić nazwę tego modelu?
ng-pattern="field.pattern"
tego, czego naprawdę chciałempattern="{{field.pattern}}"
. Trochę mylące, że angular zwykle zapewnia pomoc dla dynamicznych atrybutów, ale tym razem napisał swoją własną walidację po stronie klienta i nadał jej tę samą nazwę.Możesz użyć czegoś takiego
scopeValue[field]
, ale jeśli twoje pole znajduje się w innym obiekcie, będziesz potrzebować innego rozwiązania.Aby rozwiązać wszelkiego rodzaju sytuacje, możesz użyć tej dyrektywy:
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); } }; }]);
Przykład HTML:
<input dynamic-model="'scopeValue.' + field" type="text">
źródło
ng-model="{{ variable }}"
:)Skończyło się na tym, że zrobiłem coś takiego:
W kontrolerze:
link: function($scope, $element, $attr) { $scope.scope = $scope; // or $scope.$parent, as needed $scope.field = $attr.field = '_suffix'; $scope.subfield = $attr.sub_node; ...
więc w szablonach mógłbym używać całkowicie dynamicznych nazw, a nie tylko pod pewnym zakodowanym elementem (jak w przypadku „Odpowiedzi”):
<textarea ng-model="scope[field][subfield]"></textarea>
Mam nadzieję że to pomoże.
źródło
Aby uzupełnić odpowiedź udzieloną przez @abourget, wartość scopeValue [pole] w następnym wierszu kodu może być niezdefiniowana. Spowodowałoby to błąd podczas ustawiania podpola:
<textarea ng-model="scopeValue[field][subfield]"></textarea>
Jednym ze sposobów rozwiązania tego problemu jest dodanie atrybutu ng-focus = "nullSafe (field)", tak aby kod wyglądał jak poniżej:
<textarea ng-focus="nullSafe(field)" ng-model="scopeValue[field][subfield]"></textarea>
Następnie definiujesz nullSafe (pole) w kontrolerze, jak poniżej:
$scope.nullSafe = function ( field ) { if ( !$scope.scopeValue[field] ) { $scope.scopeValue[field] = {}; } };
Gwarantuje to, że scopeValue [pole] nie jest niezdefiniowane przed ustawieniem jakiejkolwiek wartości na scopeValue [pole] [subfield].
Uwaga: nie można użyć funkcji ng-change = "nullSafe (field)", aby osiągnąć ten sam wynik, ponieważ ng-change ma miejsce po zmianie modelu ng, co spowodowałoby błąd, jeśli scopeValue [pole] jest niezdefiniowane.
źródło
Lub możesz użyć
<select [(ngModel)]="Answers[''+question.Name+'']" ng-options="option for option in question.Options"> </select>
źródło