Angularjs - $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
.run(function ($rootScope) {
$rootScope.rsLabels = {
welcome: 'Welcome'
};
$rootScope.rsUser = {
firstName: 'Joe'
};
});
спасибо!
6 ответов
из моих экспериментов \ опыта кажется, что, поскольку все $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>'
};
});
Не рекомендуется использовать корневую область для установки и получения свойств в приложении angular. Попробуйте использовать $cacheFactory, так как таким образом вы также можете кэшировать некоторые значения по различным запросам. ($cacheFactory документы)
иногда мне приходится использовать $scope.$ root:
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;
});
};
}]);
поработав над этим же вопросом в течение некоторого времени, я подумал, что стоит отметить то, что было упущено в первом посте. Вот мой оригинальный код:
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 и другим функциям. Я сделал это так из-за своего окружения...
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})
}
});
Если вы можете, лучший способ-это решение Mike. если нет, попробуйте мое решение.