AngularJS에서 동적 모델 이름을 어떻게 설정할 수 있습니까?


91

동적 질문으로 양식을 채우고 싶습니다 ( 여기에 바이올린 ).

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

평가 된 Answers [ "GenderQuestion"] 대신 모델이 문자 그대로 Answers [ "{{question.Name}}"] 인 것을 제외하고 모든 것이 작동합니다. 모델 이름을 어떻게 동적으로 설정할 수 있습니까?

답변:


121

http://jsfiddle.net/DrQ77/

javascript 표현식을 ng-model.


1
나는 그것을 시도했다는 것을 맹세합니다. 대단히 감사합니다. 나는 실제로 다른 경로를 갔고 모델을 질문으로 설정했습니다 .Answer (조금씩 업데이트 된 바이올린을 내놓을 것입니다), 더 직접적인 답변으로 판명되었습니다 (jQuery 사고 방식에서 벗어나야 함). 내가 원래 미래를 위해 계획했던 방식대로 할 수 있다는 사실을 알게되어 기쁩니다. 다시 한 번 감사드립니다!
Mike Pateras 2012 년

이것이 다른 사람에게 도움이 될 경우 비슷한 문제가 있었지만 내 문제는 ng-pattern="field.pattern"내가 정말로 원하는 것이 pattern="{{field.pattern}}". 앵귤러는 일반적으로 동적 속성에 대한 도우미를 제공하지만 이번에는 클라이언트 측 유효성 검사를 작성하고 동일한 이름을 부여했습니다.
colllin

실제 목적이 없는데 왜 빈 개체 (답변)를 만들기로 결정 했습니까? ng-model로만 사용하고있는 것 같고,이 외에는 목적이없는 것 같은데 모두 생략하고 그렇게하게 만드는 건 어떨까요? 명확히 해주시겠습니까?
Devner 2014

원래 코드에서 최소한의 변경 만 시도했습니다. Mike의 수정 된 코드 ( jsfiddle.net/2AwLM/23 )를 보면 그는 그것을 제거하기로 결정했습니다.
Tosh 2011

이것에 대해 정말 감사합니다. 나를 많이 도왔다. 여기를 참조하십시오 : stackoverflow.com/questions/34081903/...
알버트

31

이와 같은 것을 사용할 수 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">

예상대로 작동합니다.
C0ZEN

1
예이! 이것이 내가 필요했던 것입니다! 감사합니다!
Snapman

2
좋은. 하지만 여전히 우리가 사용할 수 있으면 좋겠다 ng-model="{{ variable }}":)
davidkonrad

13

내가 한 일은 다음과 같습니다.

컨트롤러에서 :

link: function($scope, $element, $attr) {
  $scope.scope = $scope;  // or $scope.$parent, as needed
  $scope.field = $attr.field = '_suffix';
  $scope.subfield = $attr.sub_node;
  ...

따라서 템플릿에서 특정 하드 코딩 된 요소 (예 : "Answers"사례) 아래가 아니라 완전히 동적 이름을 사용할 수 있습니다.

<textarea ng-model="scope[field][subfield]"></textarea>

도움이 되었기를 바랍니다.


3

@abourget에서 제공하는 답변을보다 완전하게 만들기 위해 다음 코드 줄에서 scopeValue [field] 값을 정의하지 않을 수 있습니다. 이로 인해 하위 필드를 설정할 때 오류가 발생합니다.

<textarea ng-model="scopeValue[field][subfield]"></textarea>

이 문제를 해결하는 한 가지 방법은 ng-focus = "nullSafe (field)"속성을 추가하는 것이므로 코드는 다음과 같습니다.

<textarea ng-focus="nullSafe(field)" ng-model="scopeValue[field][subfield]"></textarea>

그런 다음 아래와 같은 컨트롤러에서 nullSafe (field)를 정의합니다.

$scope.nullSafe = function ( field ) {
  if ( !$scope.scopeValue[field] ) {
    $scope.scopeValue[field] = {};
  }
};

이렇게하면 값을 scopeValue [field] [subfield]로 설정하기 전에 scopeValue [field]가 정의되지 않은 상태가 아닙니다.

참고 : ng-change = "nullSafe (field)"를 사용하여 동일한 결과를 얻을 수 없습니다. ng-model이 변경된 후 ng-change가 발생하므로 scopeValue [field]가 정의되지 않은 경우 오류가 발생합니다.


1

또는 사용할 수 있습니다

<select [(ngModel)]="Answers[''+question.Name+'']" ng-options="option for option in question.Options">
        </select>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.