2013-05-17 2 views
30

Я видел this и this, но похоже, что может быть более простой способ.Подождите, пока переменная области не загрузится, прежде чем использовать ее в виде в angular.js

На мой взгляд, у меня есть несколько параметров меню, которые контролируются с помощью разрешения - т. Е. Не каждый может видеть представление «Панель мониторинга». Так что в моем пункте меню, на мой взгляд у меня есть что-то вроде следующего:

<li ng-show="validatePermission('Dashboard')">Dashboard</li> 

В мой контроллер у меня есть метод validatePermission определить, где он смотрит на разрешения текущего пользователя. Например:

$scope.validatePermission = function(objectName) { 
    if $scope.allPermissions...... 

Кроме того, в моем контроллере я загружаю эти разрешения через $ HTTP вызова:

$http.get('permissions/' + userid + '.json').success(function(data) { 
    $scope.allPermissions = data;.... 

Вопрос заключается в том, что $ scope.allPermissions не напиваться до просмотра моделей вызов validatePermission. Как я могу дождаться загрузки всех пакетов до отображения рендеринга?

ответ

10

Функция validatedPermission возвращает false, если allPermissions не был загружен. Таким образом, элемент с вашим ng-show не будет отображаться до тех пор, пока не будет загружен allPermissions.

В качестве альтернативы, положите ng-show="allPermissions" на прилагаемый <ul> или <ol>.

+0

Спасибо. Означает ли это, что функция validatePermissions будет вызываться несколько раз? то есть, возможно, изначально, когда allPermissions не загружается, тогда действительно ли это будет просто вызвать его снова после его загрузки. Как он узнал, чтобы снова позвонить (после его загрузки)? Разве это не будет называться один раз? –

+0

Я выбрал это, потому что он кажется самым простым и работает - хотя я не уверен на 100% почему. Я предполагаю, что Angular первоначально вызывает функцию validatePermissions при отображении представления, и даже если allPermissions не загружается (и я возвращаю false), он снова вызовет эту функцию при загрузке allPermissions - как-то известно, чтобы снова вызвать эту функцию. –

+0

@ArthurFrankel - Да, выражение в 'ng-watch' будет оцениваться один раз за цикл. Угловое в целом работает так: «ng-show» не «показывает, истинно ли выражение», это «show * while», выражение «true». Другие варианты хороши, если вам действительно нужно разобраться, пока не будут загружены разрешения, но, насколько я могу судить, вас здесь нет. –

5

Вы также можете указать на своем маршрутном контроллере объект разрешения, который будет дожидаться разрешения этого объекта до его отображения.

Из угловых документов: - {.} = Объект - https://docs.angularjs.org/api/ngRoute/provider/$routeProvider

Решимости Необязательной карты зависимостей, которые должны быть введены в контроллер. Если какая-либо из этих зависимостей является обещанием, они будут разрешены и преобразованы в значение до создания экземпляра контроллера и запускается событие $ routeChangeSuccess. Объект карты:

ключ - {строка}: имя зависимости, которое должно быть введено в контроллер. factory - {string | function}: Если строка является псевдонимом для службы. В противном случае, если функция, то она вводится, а возвращаемое значение рассматривается как зависимость. Если результат является обещанием, он разрешается до того, как его значение будет введено в контроллер.

Контрольная группа Google, а также: https://groups.google.com/forum/#!topic/angular/QtO8QoxSjYw

+1

Разрешите звуки правильно ... позвольте мне попробовать. –

21

Вы спрашиваете:

Как я могу ждать allPermissions быть загружен до того, как вид делает?

Чтобы предотвратить визуализацию всего изображения, вы должны использовать разрешение. Вы не должны использовать библиотеку обещание, хотя, так как $ HTTP возвращает обещание:

var app = angular.module('app'); 

app.config(function ($routeProvider) { 
    $routeProvider 
    .when('/', { 
     templateUrl : 'template.html', 
     controller : 'MyCtrl', 
     resolve : MyCtrl.resolve 
    }); 
}); 

function MyCtrl ($scope, myHttpResponse) { 
    // controller logic 
} 

MyCtrl.resolve = { 
    myHttpResponse : function($http) { 
    return $http({ 
     method: 'GET', 
     url: 'http://example.com' 
    }) 
    .success(function(data, status) { 
     // Probably no need to do anything here. 
    }) 
    .error(function(data, status){ 
     // Maybe add an error message to a service here. 
     // In this case your $http promise was rejected automatically and the view won't render. 
    }); 
    } 
} 

Но если вы просто хотите, чтобы скрыть панель < Ли >, то делать, как предложил Джо Gauterin. Вот вам очень просто example plunkr, если вам это нужно.

4

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

http://docs.angularjs.org/api/ng/directive/ngCloak

, если вы по-прежнему наблюдаем эффект «мерцания».

Согласно angularjs документации:

директива ngCloak используется для предотвращения углового шаблона HTML от того кратко отображается в браузере в необработанном (неоткомпилированной) форме, когда приложение загружается. Используйте эту директиву, чтобы избежать нежелательного эффекта мерцания, вызванного отображением шаблона html.

+0

Добро пожаловать в переполнение стека! Хотя это теоретически может ответить на вопрос, [было бы предпочтительнее] (http://meta.stackexchange.com/q/8259) включить основные части ответа здесь и предоставить ссылку для справки. – user13500

+0

'ng-cloak' помог мне в прошлом раньше с такой же ситуацией – Sevenearths

2

Обертывание кода в нг-если исправили проблему для меня:

<div ng-if="dependentObject"> 
    <!-- code for dependentObject goes here --> 
</div> 
Смежные вопросы