Angular + ngClass не применяется за пределами ngView

У меня есть приложение с двумя контроллерами.

http://jsfiddle.net/waxolunist/UDf2m/4/

Вы видите, что я применяю логическое значение к области видимости. В зависимости от этой переменной я хочу применить класс с ng-class. Но это не работает вне ngview.

Это не работает:

<div ng-class="{'red': isRed}" >
  <div ng-view></div>
</div>

Это работает:

<div>
  <div ng-class="{'red': isRed}" ng-view></div>
</div>

Это работает, когда я применяю переменную к rootScope. Я также могу заставить его работать, когда я делаю isRed функцией, но затем эта функция вызывается при каждом щелчке несколько раз, что, как я подозреваю, вызывает проблемы с производительностью в более крупном приложении.

Как я могу правильно оценить ngclass вне ngview?

Обновлять:

Я собираю здесь возможные решения:

Рутскоп

Как упоминалось ранее и Franci, применение состояния к корневой области работает: http://jsfiddle.net/waxolunist/UDf2m/9/

Недостаток: загрязняет rootScope.

Функция

Сделайте это вызовом функции. http://jsfiddle.net/waxolunist/UDf2m/12/

Недостаток: функция вызывается очень, очень часто (4 раза в этом небольшом примере).


person Christian    schedule 15.07.2014    source источник


Ответы (2)


Область действия ваших контроллеров доступна только внутри элемента ui-view. Вне пользовательского интерфейса доступен только $rootScope. Что вы можете сделать, если ваше приложение действительно требует такой структуры, так это внедрить $rootScope и добавить к нему свойство isRed. У вас есть $rootScope, уже закомментированный в вашем коде, который должен заставить его работать.

myApp.controller('MyCtrl', function($scope, $routeParams, $rootScope) {
    console.log('MyCtrl');

    /*
    $rootScope.isRed = function() {
        console.log('isRed');
        return angular.isDefined($routeParams.resource);
    };
    */

    $rootScope.isRed = angular.isDefined($routeParams.resource);
    //$rootScope.isRed = true;
    $scope.resource = $routeParams.resource;
});
person Franci    schedule 15.07.2014
comment
Это делает isRed=true только тогда, когда MyCtrl загружается по ссылке. - person Jayantha Lal Sirisena; 15.07.2014
comment
Я понимаю, но вы по-прежнему не можете получить доступ к области MyCtrl за пределами элемента ng-view, поэтому единственный способ сделать его доступным глобально — добавить метод в $ rootScope. Я сделал это в приведенном выше коде, но оставил его закомментированным. Это не очень хорошая практика, но это единственный способ для вас иметь возможность общаться с внешней областью внутри контроллера. - person Franci; 15.07.2014
comment
Да, это правда . Но вы также можете добавить контроллер за пределами ng-view, как и в моем ответе. Это не нарушит никакой передовой практики. :) - person Jayantha Lal Sirisena; 15.07.2014
comment
Судя по вашему примеру, вы добавляете контроллер при маршрутизации, а не в своем HTML. В случае, если вы хотите использовать разрешение для загрузки данных при маршрутизации, вы хотите сохранить его таким образом. Позже у вас могут возникнуть проблемы, если вы объявите контроллер в своем HTML-элементе, который хотите привязать к определенному маршруту. Во всяком случае, надеюсь, что это поможет. - person Franci; 15.07.2014
comment
Я приму этот ответ, потому что его проще всего реализовать. - person Christian; 16.07.2014

Вам нужно использовать ng-controller для корневого уровня

<div ng-app="myApp" ng-controller="MyCtrl">    
    <ul>
        <li><a href="#/">Home</a></li>
        <li><a href="#/some">A resource</a></li>
        <li><a href="#/some/arbitrary/url">A deep linked resource</a></li>
    </ul>
    <div ng-class="{'red': isRed}" >
         <div ng-view></div>
    </div>
</div>

См. здесь, все работает нормально

person Jayantha Lal Sirisena    schedule 15.07.2014
comment
вам НЕ нужно повторно связывать ng-app, предполагая, что оно уже связано (что мы и сделаем, поскольку angular делает что-то). - person Shelby L Morris; 15.07.2014
comment
@sxnine, да, я пропустил это. - person Jayantha Lal Sirisena; 15.07.2014
comment
@Jayantha Прошу прощения, но это не работает, как ожидалось. Класс всегда применяется. Правильное поведение такое же, как в этой скрипке: проблема с этой скрипкой - это rootScope, который я не хочу загрязнять. - person Christian; 15.07.2014
comment
Действительно странное поведение, которое я вижу, похоже на этот пример: jsfiddle.net/waxolunist/UDf2m/10 isRed дает правильное значение, но класс не применяется, потому что он оценивается позже. - person Christian; 15.07.2014
comment
Ах хорошо. Я думаю, jsfiddle.net/UDf2m/15 это то, что вы ожидали. Я добавил еще один контроллер для родительского уровня ваших контроллеров для обработки класса. Надеюсь, поможет.. - person Jayantha Lal Sirisena; 15.07.2014
comment
Теперь вы используете функциональный подход, который я описал ранее. Вероятно, нет никакого способа обойти эти два варианта. - person Christian; 15.07.2014