2015-09-17 2 views
0

В моем контроллере I проходных вопросов в анкете:Как получить выбранное значение из нг-опциона внутри нг-повтор

for (var j = 0; j < s.Questions.length; j++) { 
    var q = s.Questions[j]; 
    var aq = datacontext.getAnsweredQuestion(propertySurvey.ID, q.ID); 
    if (q.QuestionType === 'SingleAnswer') { 
     q.dropdown = true; 
     q.selectedOption = aq.ActualAnswers.length > 0 ? 
          aq.ActualAnswers[0].AnswerID : null; 
     q.optionChanged = function() { 
      var debug = q.selectedOption; //ERROR - this is undefined 
      aq.toggleAnswer(q.selectedOption); 
     } 
    } 
    //etc 
} 

На моем взгляде, я Переберите вопросы:

<div class="card" ng-repeat="q in s.Questions"> 
    <div class="item item-divider">{{q.Text}}</div> 
    <div class="item" ng-if="q.dropdown"> 
     <select ng-model="q.selectedOption" 
       ng-options="va.AnswerID as va.Text for va in q.ValidAnswers" 
       ng-change="q.optionChanged()"> 
      <option>--Select--</option> 
     </select> 
    </div> 
</div> 

При просмотре в браузере отображается правильный selectedOption и вызывается функция q.optionChanged(). Но внутри этой функции, q.selectedOption неопределен

EDIT Эта функция появляется на работу. Но я не могу объяснить, почему!

q.optionChanged = function() { 
    var debug = q.selectedOption; 
    var answerid = this.selectedOption; 
    aq.toggleAnswer(answerid); 
} 

ответ

1

Причина в том, что вы создаете функцию с закрытием внутри цикла, что вызывает это неинтуитивное поведение. Читайте: Creating closures in loops: A common mistake

Что в конечном итоге происходит в том, что внутренняя функция захватывает в петлю последнего q, для которых (по какой-то причине, возможно, не показано в коде здесь), q.optionChanged является undefined.

В отличие от этого, this связан справа q как указано выражением в ng-change="q.optionChanged()".

Чтобы исправить, используйте функцию генератора для создания функции для каждой итерации цикла, например, так:

for (var j = 0; j < s.Questions.length; j++) { 
    var q = s.Questions[j]; 
    var aq = datacontext.getAnsweredQuestion(...); 

    // ... 

    q.optionChanged = makeOptionChangeFn(q, aq) 

    // ... 

} 

function makeOptionChangeFn(q, aq){ 
    return function(){ 
    aq.toggleAnswer(q.selectedOption); 
    } 
} 

Использование this работал бы, если только нужно ссылаться на право q, но вы также должны aq , поэтому необходим генератор функций.

-1

Для того, чтобы автоматически выбрать опцию из контроллера, в нг-модели должна содержать ссылку на массив элемента. Присвойте q.selectedOption весь товар из aq.ActualAnswers. Вам нужно будет реорганизовать ваше понимание.

// in the controller 
q.selectedOption = aq.ActualAnswers.length > 0 ? 
          aq.ActualAnswers[0] : null; 

// in the view 
ng-options="va as va.Text for va in q.ValidAnswers" 

Это причинило мне боль в прошлом. Убедитесь, что вы тщательно прочитали документацию:

https://docs.angularjs.org/api/ng/directive/ngOptions

+0

Опция автоматически выбирается. Но я не могу получить значение вновь выбранного элемента в функции 'optionChanged'. 'ValidAnswers' и' ActualAnswers' - это два отдельных массива. Я пробовал код, как вы написали, я думаю, что привязываю ng-модель к «ActualAnswer», но привязывая параметры к «ValidAnswer», а это означает, что он больше не будет автоматически выбираться. Я обнаружил, что 'this.selectedOption' вместо' q.selectedOption', как представляется, содержит значение ... – Colin

+0

Почему голос? Не я. – Colin