#javascript #angularjs #templates #scope #directive
#javascript #angularjs #шаблоны #область #директива
Вопрос:
Я довольно новичок в директивах Angular, и у меня много проблем с тем, чтобы заставить это делать то, что я хочу. Вот основы того, что у меня есть:
Контроллер:
controller('profileCtrl', function($scope) {
$scope.editing = {
'section1': false,
'section2': false
}
$scope.updateProfile = function() {};
$scope.cancelProfile = function() {};
});
Директива:
directive('editButton', function() {
return {
restrict: 'E',
templateUrl: 'editbutton.tpl.html',
scope: {
editModel: '=ngEdit'
}
};
});
Шаблон (editbutton.tpl.html ):
<button
ng-show="!editModel"
ng-click="editModel=true"></button>
<button
ng-show="editModel"
ng-click="updateProfile(); editModel=false"></button>
<button
ng-show="editModel"
ng-click="cancelProfile(); editModel=false"></button>
HTML:
<edit-button ng-edit="editing.section1"></edit-button>
Если это непонятно, я хочу, чтобы <edit-button>
тег содержал три разные кнопки, каждая из которых взаимодействовала с любым переданным в нее свойством области ng-edit
. При нажатии они должны изменить это свойство, а затем вызвать соответствующий метод области.
Как и сейчас, нажатие кнопок корректно изменяет значения $scope.editing
, но методы updateProfile
и cancelProfile
не работают. Возможно, я далек от понимания того, как правильно использовать директивы, но у меня возникли проблемы с поиском примера в Интернете, который помог бы мне выполнить то, что я пытаюсь сделать. Любая помощь была бы оценена.
Ответ №1:
Одним из способов было бы вызвать функции с помощью $parent
.
<button ng-show="editModel" ng-click="$parent.cancelProfile(); editModel=false">b3</button>
Другой способ (и, вероятно, лучший способ) — настроить изолированную область действия вашей директивы так, чтобы она содержала ссылки на эти функции контроллера:
app.directive('editButton', function() {
return {
restrict: 'E',
templateUrl: 'editbutton.tpl.html',
scope: {
editModel: '=ngEdit',
updateProfile: 'amp;',
cancelProfile: 'amp;'
}
};
});
Затем вы передаете функции через HTML:
<edit-button ng-edit="editing.section1" update-profile='updateProfile()' cancel-profile='cancelProfile()'></edit-button>
Комментарии:
1. Отлично, спасибо. Я склонен использовать ваш первый пример, поскольку два метода всегда будут одинаковыми для всех директив, и это уменьшит количество посторонних html. Что заставляет вас говорить, что второй способ является «лучшим способом»?
2. @futurityverb, второй метод является более общим. Если вам нужен экземпляр директивы с немного другим поведением, вы можете просто передать другой метод, который должен быть вызван. Кроме того, если вы начнете вкладывать свою директиву в другие директивы,
$parent
может больше не ссылаться на область контроллера, а на какую-либо другую промежуточную область.3. Подтолкнуло меня в правильном направлении, но что, если я хочу передать аргументы методам, используя ваш второй пример?
4. Передайте свой аргумент в качестве объекта. Что-то вроде этого:
update-profile='updateProfile({message: testMessage})'
.