AngularJS ─ не может получить область по ссылке из контроллера директивы
У меня есть пример приложения с очень простой структурой (вы можете увидеть его здесь: http://plnkr.co/edit/5VAqUQsqKFGoteahacR2?p=preview): файл index.html содержит шаблон (app/templates/home.html), который, в свою очередь, включает шаблон директивы:
<div class="included" ng-include="'app/templates/outer-directive-2.html'"></div>
Включает следующую директиву:
<p>This is the included file <b>app/templates/outer-directive-2.html</b></p>
<div inner2="context"></div>
Значение param inner2 является ключом для объекта $scope.contents, который определен в контроллере contentsCtrl:
app.controller('contentsCtrl', function($scope,$rootScope){
$scope.contents = {
context: "Context for investigations here."
}
});
Этот ключ необходим для извлечения поля объекта в скрипте директивы (app/scripts/directives/defaultDirective.js):
app.directive('inner2', function(){
return{
restrict: 'A',
replace: true,
scope: {
inner2: '@',
contents: '&'
},
templateUrl: 'app/templates/inner-directive-2.html',
controller: function($scope){
$scope.getStuff = function(){
console.log('$scope.inner2, $scope.contents', {
// returns the key "context"
'$scope.inner2':$scope.inner2,
// returns function (???)
'$scope.contents':$scope.contents,
// returns "undefined"
'$scope.context':$scope.contents[$scope.inner2]
});
}
}
};
});
Содержимое этой последней свернутой директивы (app/templates/inner-directive-2.html) очень просто:
<div class="included" title="{{inner2}}">
<p>Hello, I am the inner directive 2</p>
<span class="pseudolink" ng-click="getStuff()">Click me</span> and check console message!
</div>
Таким образом, идея состоит в том, чтобы получить $scope.contents[object_key], вызвав getStuff(). Но он не видит $scope.contents. Я думал, что это можно сделать, связав содержимое изолированного параметра области (см. Выше) с внешней областью действия:
scope: {
....
contents: '&'
},
... но он не возвращает объект области, вместо этого он возвращает функцию. Возможно, что-то здесь не так. Вопросы: 1. Почему функционируют и откуда они берутся? 2. Могу ли я получить $scope.contents каким-то образом и как?
2 ответа
Вы уже получаете содержимое области. Просто вы не определили маршрут по умолчанию к дому, а установили 404. Пожалуйста, проверьте обновленный плункер - http://plnkr.co/edit/BlXBqK?p=preview
Дайте мне знать, если вы ищете что-то еще.
app.config(function($stateProvider, $urlRouterProvider){
$urlRouterProvider.otherwise("/home");
$stateProvider
.state('home',{
url: "/home",
templateUrl: 'app/templates/home.html'
})
.state('error',{
url: "/404",
templateUrl: "app/templates/404.html"
});
});
Согласно угловым документам:
& или &attr - предоставляет способ выполнить выражение в контексте родительской области. Если имя атрибута не указано, то предполагается, что имя атрибута совпадает с локальным именем. Учитывая и область определения определения изолированной области: { localFn:'&myAttr' }, свойство изолированной области localFn будет указывать на оболочку функции для выражения count = count + value. Часто желательно передавать данные из изолированной области через выражение в родительскую область. Это можно сделать, передав карту имен и значений локальных переменных в оболочку выражения fn. Например, если выражение является приращением (количеством), то мы можем указать значение суммы, вызвав localFn как localFn({amount: 22})
поэтому scope.contents в вашей директиве будет функцией-оболочкой. Вы должны либо передать свой объект содержимого в область действия директивы, либо изменить doStuff, чтобы выполнить его в контексте родительской области.
Как и в документе (пожалуйста, посмотрите на пример с приращением (количеством)), ваш doStuff должен находиться в родительской области видимости. И из директивы вы можете передать переменные локали