AngularJS: сделать ng-модель доступной вне ng-repeat

В моем приложении AngularJS я просматриваю объект массива и отправляю значение на радиовход как значение. Общая идея состоит в том, что пользователь выбирает переключатель и значение, возвращающееся в $ routeParams. К сожалению, переменная {{ modelSelected }}, похоже, недоступна вне ng-repeat. Почему? Первый никогда не показывает переменную {{ modelSelected }}.

Создает ли AngularJS объект ScopeChild в ng-repeat?

Ссылка на мой пример jsfiddle

<html ng-app>
    <body ng-init="models = [{name:'Sam'},{name:'Harry'},{name:'Sally'}]">
        <h3> Selected {{ modelSelected }} shown outside paragraph</h3>

        <div ng-repeat="model in models">
            <p>{{ model.name }} -
                <input ng-model="modelSelected" type="radio" name="patient" value="{{ model.name }}" required>
            </p>
             <h3> Selected {{ modelSelected }} shown inside paragraph</h3>

        </div>
    </body>
</html>

person neurix    schedule 06.08.2014    source источник


Ответы (3)


При работе с примитивами или использованием привязок обычно старайтесь использовать . в связываемом свойстве модели. Таким образом, когда создается дочерняя область видимости, прототипное наследование переносит свойства (которые являются ссылочными типами) до дочерних элементов. (использование $parent почти всегда считается взломом). В вашем случае свойство modelSelected является примитивом (даже если оно присутствует в родительской области), а ng-repeat создает дочернюю область, которая не находит это свойство (поскольку наследование не переносит его, даже если оно присутствовало) и создает новую свойство в своей области, поэтому внесенные в нее изменения не видны во внешней области.

Инициализируйте свойство в области видимости как объект selection={} в вашей области (в вашем примере это будет внешняя область). И привяжите модель как ng-model="selection.modelSelected

Ex:-

<body ng-init="models = [{name:'Sam'},{name:'Harry'},{name:'Sally'}]; selection={}">
        <h3> Selected {{ selection.modelSelected }} shown outside paragraph</h3>

        <div ng-repeat="model in models">
            <p>{{ model.name }} -
                <input ng-model="selection.modelSelected" type="radio" name="patient" value="{{ model.name }}" required>
            </p>
             <h3> Selected {{ selection.modelSelected }} shown inside paragraph</h3>

        </div>
 </body>

Демо

Прочтите: Общие сведения об областях

person PSL    schedule 06.08.2014
comment
Я бы предпочел это использованию $parent. Это лучшая практика, и вам не придется делать $parent.$parent.$parent, чтобы перейти к переменной в нужной вам области. - person TheSharpieOne; 07.08.2014
comment
@TheSharpieOne Я не могу с этим согласиться, кроме этого ребенку нужно знать о существовании самого родителя, что не очень хорошо. - person PSL; 07.08.2014
comment
Мне тоже нравится способ использования переменной области видимости. Уже реализовано и отлично работает. Спасибо за объяснение. Очень ценится. - person neurix; 07.08.2014

да. Он действительно создает новую область, которая наследует родительскую область. Используйте $ parent.modelSelected для доступа к переменной родительской области.

<body ng-init="models = [{name:'Sam'},{name:'Harry'},{name:'Sally'}]">
     <h3> Selected {{ modelSelected }} shown outside paragraph</h3>

    <div ng-repeat="model in models">
        <p>{{ model.name }} -
            <input ng-model="$parent.modelSelected" type="radio" name="patient" value="{{ model.name }}" required>
        </p>
         <h3> Selected {{ modelSelected }} shown inside paragraph</h3>

    </div>
</body>
person Rajkumar Madhuram    schedule 06.08.2014
comment
Спасибо за ваш ответ. Прочитав разные ответы, я думаю, что предпочитаю ответ @PSL с переменной области. Боюсь, что начну связывать переменные $ parent. - person neurix; 07.08.2014
comment
Конечно. нп. Изначально я собирался добавить еще одну переменную в родительскую область видимости, но для краткости просто указал вам на $ parent. Очевидно, что везде использовать $ parent нецелесообразно, но в данном случае это не казалось неразумным. Однако хорошее объяснение от @PSL. - person Rajkumar Madhuram; 07.08.2014

{{modelSelected}} не будет доступен за пределами ng-repeat из-за того, как область видимости работает в AngularJS (см. https://docs.angularjs.org/guide/scope)

Области действия организованы в иерархическую структуру, которая имитирует структуру DOM приложения.

Итак, поскольку элемент <h3>, из которого вы пытаетесь получить доступ к объекту {{modelSelected}}, находится за пределами области действия итератора, объект недоступен.

person Spaceman Spiff    schedule 06.08.2014
comment
Это можно сделать несколькими способами. На самом деле вы не отвечаете на вопрос, а просто повторяете проблему. - person Malkus; 07.08.2014
comment
Привет, Ян, Спасибо за ссылку на документацию по области применения. - person neurix; 07.08.2014