AngularJS: передать переменную $scope в качестве атрибута директивы
Я пытаюсь передать значения переменной $scope в пользовательскую директиву как атрибут, но не работает.
Вот код HTML:
<ul ng-repeat="q in questions">
<li>
{{q.question}}
<check-list name="{{q.id}}"></check-list>
</li>
</ul>
Директива <check-list name={{q.id}}></check-list>
, и вот код директивы:
app.directive('checkList',function(){
return {
restrict:'E',
template: function(elem,attrs){
console.log(attrs.name);
return '</br> <input type="radio" /> Yes </br> <input type="radio" /> No'
},
link:function(scope,elem,attrs){
}
};
})
Я регистрирую атрибут attrs.name
, но значение, которое я получаю, составляет "{{q.id}}"
вместо фактического значения q.id
Ответы
Ответ 1
Я предполагаю, что вы хотите сделать инъекцию объекта scope из контроллера в свою директиву. Таким образом, вы можете определить свою директиву как
app.directive('checkList',function(){
return {
restrict:'E',
scope: {
name: "="
}
template: '{{name}}</br> <input type="radio" /> Yes </br> <input type="radio" /> No',
link:function(scope,elem,attrs){
}
};
}
И, на ваш взгляд, вы можете ссылаться на свою директиву как
<check-list name="q.id"></check-list>
Ответ 2
В директивах атрибуты являются просто строками.
В функции шаблона все, что вы можете сделать, это использовать строковое значение атрибута. Если вы хотите использовать оцениваемое или интерполированное значение атрибута, у вас есть несколько вариантов:
1) Используйте изолированную область
app.directive('checkList', function() {
return {
restrict:'E',
scope: {
name: '&'
}
template: '</br> <input type="radio" /> Yes </br>{{name()}} <input type="radio" /> No'
link: function(scope, elem, attrs) {
}
};
});
<ul ng-repeat="q in questions">
<li>
{{q.question}}
<check-list name="q.id"></check-list>
</li>
</ul>
2) Inject $интерполяция или $parse для оценки интерполяции или выражения вручную в функции ссылок
app.directive('checkList', function($interpolate) {
return {
restrict:'E',
template: '</br> <input type="radio" /> Yes </br>{{name}} <input type="radio" /> No'
link:function(scope,elem,attrs){
scope.name = $interpolate(attrs.name)(scope);
}
};
});
<ul ng-repeat="q in questions">
<li>
{{q.question}}
<check-list name="{{q.id}}"></check-list>
</li>
</ul>
2a) И, наконец, $parse
app.directive('checkList',function($parse){
return {
restrict:'E',
template: '</br> <input type="radio" /> Yes </br>{{name}} <input type="radio" /> No'
link:function(scope,elem,attrs){
scope.name = $parse(attrs.name)(scope);
}
};
});
<ul ng-repeat="q in questions">
<li>
{{q.question}}
<check-list name="q.id"></check-list>
</li>
</ul>
Ответ 3
Я думаю, вам нужно передать "q.id" вместо name= {{q.id}}, если $scope.q.id определен в вашем соответствующем контроллере.
<check-list name="q.id"></check-list>
Ответ 4
Или передайте всю область действия своей директиве:
app.directive('checkList',function(){
return {
restrict:'E',
scope: true, //scope
template: function(elem,attrs){
console.log(attrs.name);
return '</br> <input type="radio" /> Yes </br> <input type="radio" /> No'
},
link:function(scope,elem,attrs){
var question = scope.q; //get your question here
}
};
})
Я рекомендую вам передать только ссылочный тип в качестве аргумента вашей директивы. Не передавайте примитивные типы (q.id
может быть целым числом). Передайте question
. Это все о том, как angularjs использует прототипическое наследование.
Scope
- сложная тема в угловом. Смотрите это: https://github.com/angular/angular.js/wiki/Understanding-Scopes