#angularjs #angularjs-directive
#angularjs #angularjs-директива
Вопрос:
На моей html-странице у меня есть кнопка и фрагмент директивы, вот так:
<button ng-click="showProfile();"></button>
<profile ng-if="isProfile==true"></profile>
В моем контроллере я инициализировал $scope.isProfile variable = false
функцию, вызываемую кнопкой:
$scope.showProfile = function(contact) {
$scope.contact = contact; // this object needs to get passed to the controller that the directive initiates, but how??
$scope.isProfile = true;
};
В моем приложении у меня есть директива, определенная как таковая…
app.directive('profile', function () {
return {
templateUrl: '/contacts/profile',
restrict: 'ECMA',
controller: contactsProfileController,
link:function(scope, element, attrs) {
console.log('k');
}
};
});
Все работает, но я не могу понять, как передать $scope.contact
объект контроллеру, на который ссылается директива.
Я пытался добавить scope:scope
к возвращаемому значению {}
директивы, но безуспешно. Нужно ли мне что-то делать в link
функции? Я потратил весь день на чтение директив и устал, поэтому буду признателен за любые советы!!!
Заранее спасибо за любую помощь!
Вот как также выглядит контроллер, вызываемый из директивы:
var contactsProfileController = function($scope,contact) {
$scope.init = function() {
console.log($scope.contact); //this should output the contact value from the showProfile function.
};
....
}
Комментарии:
1. Вам не нужно ничего передавать, если вы не используете изолированную область, дочерняя область должна наследовать объект contact. Однако похоже, что ваша
showProfile
функция принимает аргумент contact, который вы не передаете, поэтому, когда она устанавливает,$scope.contact
она, вероятно, устанавливает его в значение undefined . Можете ли вы показать больше кода?
Ответ №1:
попробуйте это в вашей директиве.
<profile ng-if="isProfile==true" contact="contact"></profile>
и добавьте это в область видимости
app.directive('profile', function () {
return {
templateUrl: '/contacts/profile',
restrict: 'ECMA',
scope: {
contact: '=contact'
}
controller: contactsProfileController,
link:function(scope, element, attrs) {
console.log('k');
}
};
});
Но я вижу пару проблем из вашего кода:
— ваша функция showProfile ожидает аргумент «contact», который не передается из директивы button, поэтому он будет неопределенным.
— вы вводите зависимость «contact» в свой контроллер contactsProfileController. У вас есть служба / фабрика, объявленная с таким именем?
Вместо contact: ‘@contact’, сделайте contact: ‘=контакт’
Комментарии:
1. Так работать не будет. Вы должны использовать
'=contact'
(или'='
для краткости).'@'
будет считываться"contact"
как строка.
Ответ №2:
Поскольку ваша пользовательская директива является своего рода «компонентом», хорошей идеей будет использовать область изоляции и передавать необходимые данные (т. Е. contact
) через атрибуты.
Например.:
<button ng-click="showProfile(...)"></button>
<profile contact="contact" ng-if="isProfile"></profile>
$scope.showProfile = function (contact) {
$scope.contact = contact;
$scope.isProfile = true;
};
.directive('profile', function () {
return {
restrict: 'ECMA',
scope: {contact: '='}
templateUrl: '/contacts/profile',
controller: contactsProfileController
};
});
Тогда свойство будет доступно в области видимости (например, contactsProfileController
в $scope):
var contactsProfileController = function ($scope) {
$scope.$watch('contact', function (newValue) {
// The `contact` has changed, do something...
console.log($scope.contact);
});
...
};
Ответ №3:
Оба ваших ответа были невероятно полезными, и я смог наладить работу в считанные минуты после прочтения ваших сообщений. Большое вам спасибо!!!
Добавление contact=»контакт» в заполнитель директивы было ключевым, как и добавление объекта scope в фактический код директивы.
В итоге я получил:
<profile ng-if="isProfile===true" contact="contact"></profile>
и
.directive('profile', function () {
return {
templateUrl: '/contacts/profile',
restrict: 'ECMA',
controller: contactsProfileController,
scope: {contact: '='},
link:function(scope, element, attrs) {
}
};
});