AngularJS'de dinamik model adını nasıl ayarlayabilirim?


91

Bir formu bazı dinamik sorularla doldurmak istiyorum ( burada oynayın ):

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

Modelin, değerlendirilen Cevaplar ["Cinsiyet Sorgusu"] yerine tam anlamıyla Cevaplar ["{{soru.Adı}}"] olması dışında her şey çalışır. Bu model adını dinamik olarak nasıl ayarlayabilirim?

Yanıtlar:


121

http://jsfiddle.net/DrQ77/

Javascript ifadesini içine kolayca koyabilirsiniz ng-model.


1
Yemin ederim denedim. Çok teşekkür ederim. Aslında farklı bir yola gittim ve modeli sorgulayacak şekilde ayarladım. Cevap (birazdan güncellenmiş bir keman ortaya koyacağım), bu daha doğrudan bir cevaptı (jQuery zihniyetinden çıkmalıyım), ancak Bunu gerçekten de gelecek için planladığım şekilde yapabileceğimi bilmek harika. Tekrar teşekkürler!
Mike Pateras

Bunun başkalarına yardımcı olması durumunda, benzer sorunlar yaşıyordum ama benim sorunum, ng-pattern="field.pattern"gerçekten istediğim şey olduğunda kullanıyordum pattern="{{field.pattern}}". Açının genellikle dinamik öznitelikler için bir yardımcı sağlaması biraz kafa karıştırıcı, ancak bu sefer kendi istemci tarafı doğrulamasını yazdı ve ona aynı adı verdi.
colllin

Gerçek bir amacınız yokken neden boş bir nesne (Cevaplar) yaratmaya karar verdiniz? Görünüşe göre onu sadece ng modelinde kullanıyorsunuz ve bunun dışında herhangi bir amaç yok gibi görünüyor.Öyleyse neden onu tamamen atlayıp bu şekilde çalıştırmıyorsunuz? Lütfen açıklar mısınız?
Devner

Orijinal koddan minimum bir değişiklik yapmayı denedim. Mike'ın revize edilmiş koduna ( jsfiddle.net/2AwLM/23 ) bakarsanız, ondan kurtulmaya karar verdi.
Tosh

Bunun için çok teşekkür ederim. Bana çok yardım etti. Buraya bakın: stackoverflow.com/questions/34081903/…
Albert

31

Bunun gibi bir şey kullanabilirsiniz scopeValue[field], ancak alanınız başka bir nesnede ise başka bir çözüme ihtiyacınız olacaktır.

Her tür durumu çözmek için bu yönergeyi kullanabilirsiniz:

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 örneği:

<input dynamic-model="'scopeValue.' + field" type="text">

Beklendiği gibi çalışıyor.
C0ZEN

1
Yaşasın! Bu ihtiyacım olan şey! Teşekkür ederim!
Snapman

2
Güzel. Ama yine de sadece kullanabilseydik ng-model="{{ variable }}":)
davidkonrad

13

Sonunda yaptığım şey şöyle bir şey:

Denetleyicide:

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

bu yüzden şablonlarda tamamen dinamik isimler kullanabilirdim ve sadece belirli bir sabit kodlu öğe altında değil ("Cevaplar" durumunda olduğu gibi):

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

Bu yardımcı olur umarım.


3

@Abourget tarafından sağlanan yanıtı daha eksiksiz hale getirmek için, aşağıdaki kod satırındaki kapsamDeğeri [alan] değeri tanımsız olabilir. Bu, alt alanı ayarlarken bir hataya neden olur:

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

Bu sorunu çözmenin bir yolu, bir ng-focus = "nullSafe (alan)" özniteliği eklemektir, böylece kodunuz aşağıdaki gibi görünecektir:

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

Daha sonra aşağıdaki gibi bir denetleyicide nullSafe (alan) tanımlarsınız:

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

Bu, kapsamDeğeri [alan] değerinin kapsamDeğeri [alan] [alt alan] olarak ayarlanmadan önce tanımsız olmadığını garanti eder.

Not: Aynı sonucu elde etmek için ng-change = "nullSafe (field)" kullanamazsınız çünkü ng-change, ng-modeli değiştirildikten sonra gerçekleşir, bu da kapsamDeğeri [field] tanımsız ise bir hata verir.


1

Ya da kullanabilirsin

<select [(ngModel)]="Answers[''+question.Name+'']" ng-options="option for option in question.Options">
        </select>
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.