2014-02-12 5 views
44

Я задаю этот вопрос, потому что я не совсем ясно, как думать о rootscope как зависимость передается директиве

У меня есть директива, которая должна отображать некоторую информацию от $ rootScope ...

Я думал, что мне нужно передать $ rootScope в директиву, но когда я пишу такую ​​директиву, похоже, она работает.

.directive("myBar", function() { 
return { 
    restrict: "E", 
    transclude: true, 
    replace: true, 
    template: '<div>' + 
       '<span ng-transclude></span>' + 
       '{{rsLabels.welcome}} {{rsUser.firstName}}!' + 
       '</div>' 
} 
}) 

Когда мне нужно, чтобы это сделать?

.directive("myBar", function ($rootScope) { 
return { 
    restrict: "E", 
    transclude: true, 
    replace: true, 
    template: '<div>' + 
       '<span ng-transclude></span>' + 
       '{{rsLabels.welcome}} {{rsUser.firstName}}!' + 
       '</div>' 
} 
}) 

Могу ли я и как я могу использовать rootScope, если мне это нужно в функции связи директивы - или я должен делать это в контроллере директивы?

.directive("myBar", function ($rootScope) { 
return { 
    restrict: "E", 
    transclude: true, 
    replace: true, 
    link: function (scope, element, attrs, rootScope) { 
     rootScope.rsUser = { firstName: 'Joe' }; 
     rootScope.rsUser = { welcome: 'Welcome' }; 
    }, 
    template: '<div>' + 
       '<span ng-transclude></span>' + 
       '{{rsLabels.welcome}} {{rsUser.firstName}}!' + 
       '</div>' 
} 
}) 

Мои данные rootScope определяется в режиме выбега

.run(function ($rootScope) { 

    $rootScope.rsLabels = { 
     welcome: 'Welcome' 
    }; 

    $rootScope.rsUser = { 
    firstName: 'Joe' 
    }; 
}); 

Спасибо!

ответ

47

Из моих экспериментов \ опыта кажется, что, поскольку все $ scopes в конечном счете унаследованы от $ rootScope, вы сможете получить доступ к данным на нем, не обращаясь к нему как к службе, следуя стандартным правилам прототипа на основе javascript. Если вы должны установить свойство scope в своей директиве на false или {}, вы обнаружите, что больше не сможете получить к нему доступ.

.directive("myBar", function($rootScope) { 
    return { 
     restrict: "E", 
     scope: { /* Isolate scope, no $rootScope access anymore */ }, 
     transclude: true, 
     replace: true, 
     template: '<div>' + 
        '<span ng-transclude></span>' + 
        '{{rsLabels.welcome}} {{rsUser.firstName}}!' + 
        '</div>' 
    }; 
}); 

Пример: http://jsbin.com/bequy/1/edit

+1

ах! Я понимаю. Как отметил Курт, это не лучший способ установить свойства приложения в угловом, но мне нужно понять rootScope, и это объясняет это лучше. Спасибо. Вы случайно не знаете, как получить доступ к $ root-области в функции ссылки директивы? – GRowing

+3

Вам нужно думать, что $ rootScope является глобальным пространством имен, и вы хотите избежать его загромождения. Вы можете ввести его в свою директиву, но вся суть директив - быть компонентом без слишком большого количества внешних зависимостей. Если вам нужно что-то из $ rootScope, вы можете рассмотреть возможность его рефакторинга в службу. –

+0

Это имеет смысл. Я полагаю, что я прибегаю к использованию любого эквивалента kin dof, эквивалентного глобальным, из-за того, что вы всегда делаете данные x доступными и не знаете, как еще подойти к нему. Я использую localStorage для некоторых вещей, но теперь смотрю на cacheFactory и расширенную версию, и как они используют localstorage, я вижу свет. Благодаря! – GRowing

7

Не рекомендуется использовать область корня для установки и получения свойств в вашем угловом приложении. Попробуйте использовать $ cacheFactory, так как вы можете также кэшировать некоторые значения по различным запросам. ($cacheFactory docs)

+0

Да, я понял, используя $ rootScope, как это не лучшая идея. Спасибо за предложение кстати. Я ищу более эффективные способы создания широко доступных объектов, которые я могу использовать на сайте из разных директив. Я считаю, что документация на угловом сайте совершенно бесполезна (как и большая часть этого сайта), потому что она не объясняет ничего, что не демонстрирует реальный прецедент или, по крайней мере, логические варианты использования. В моем случае все директивы на сайте должны всегда иметь доступ к информации о пользователе и несколько других бит информации. Лучший способ? Знаете ли вы, что полезны. может быть хорошая документация? – GRowing

+0

Эй, я нашел хорошую информацию вокруг этого http://jmdobry.github.io/angular-cache/guide.html и полезного видео YT .. Спасибо за этот совет! Я очень это ценю :) И я думаю, что я буду глубже погружаться в нее как практический подход к тому, над чем я работаю. Майк, однако, обратился к моему вопросу с объяснением, поэтому я буду отмечать его ответ как правильный ответ. – GRowing

59

Вы можете сделать это так:

{{$root.rsLabels.welcome}} 
+22

Спасибо, не так. Я использую 'link: function (scope, ...) {scope. $ Root}' для доступа к '$ rootScope' из директивы. – ivkremer

+0

То же самое – karaxuna

+0

Да, я имею в виду, что я искал доступ к $ rootScope из директивы, и я не знал о свойстве $ root. Спасибо за ответ. – ivkremer

3

После трудясь прочь по этому же вопросу в течение некоторого времени, я подумал, что стоит отметить то, что пренебрегли в первый пост. Вот мой исходный код:

app.directive('countrymap', function() 
{ 
    return { 
     link: function(scope, element, attrs) { 
      scope.$watch("countryMap", function (newCountry, oldCountry) 
      { 
       setTimeout(function() 
       { 
        //function body here  
       }, 100); 
      }) 
     } 
    }; 
}]); 

Помимо более философской разработке вопроса о том, следуешь ли или не вы даже использовать $ rootScope вообще, есть один вопиюще неправильно, что с моим кодом выше, что я чувствую, что остался из Решение Майка - ссылка на $ rootScope. Если вы похожи на меня и отделены ваши директивы и контроллер файлов вам необходимо изменить код следующим образом:

app.directive('countrymap', ['$rootScope', function($rootScope) 
{ 
    return { 
     link: function(scope, element, attrs) { 
      $rootScope.$watch("countryMap", function (newCountry, oldCountry) 
      { 
       setTimeout(function() 
       { 
        //function body here 
       }, 100); 
      }) 
     } 
    }; 
}]); 

Тем не менее, есть еще один мучительный вопрос: могу ли я достичь той же цели без ссылаясь на $ rootScope в директиве? Действительно, вы можете. Вам необходимо передать изменения в свойство $ rootScope, эффективно разрешающее всем дочерним областям знать об изменениях и наблюдая за этим изменением в директиве.

Контроллер:

$rootScope.countryMap = 'thiscountry_map'; 
$rootScope.$broadcast("countryMapChanged", $rootScope.countryMap); 

Директива:

app.directive('countrymapalt', [function() 
{ 
    return { 
     link: function(scope, element, attrs) { 
      scope.$on("countryMapChanged", function(event, map) 
      { 
       setTimeout(function() 
       { 
        //function body here 
       }, 100); 
      }) 
     } 
    }; 
}]); 
1

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

app.service('myService', function ($rootScope) 
{ 
    this.removeItem = function (el) 
    { 
     console.log('rootScope: ',$rootScope); 
     return true; 
    } 
}); 


app.directive('draggable', function($document,myService) 
{ 
    return function(scope, element, attr) 
    { 
     myService.removeItem({id:1}) 
    } 
}); 

Если вы можете, то лучший способ это Майк решение. если нет, попробуйте мое решение.

3

Иногда приходится использовать $ сфера $ корня:.

app.directive('setOrdinal', function() { 
    return { 
    link: function($scope, $element, $attr) { 

     var steps = $scope.$root.steps; 

     $scope.$watch(setOrdinal, function(value) { 
     if (value) 
     { 
      // steps code here 
     } 
     }); 
    } 
    }; 
}); 

app.controller('stepController', ['$scope', '$rootScope', 'GetSteps', function ($scope, $rootScope, GetSteps) { 
    var s = $scope; 
    var r = $rootScope; 

    s.initialize = function(id) 
    { 
    GetSteps.get({id: id}, function(resp){ 
     r.steps = resp.steps; 
    }); 
    }; 
}]); 
+0

сэкономил много времени – EmptyData