Метод JavaScript ' bind` не работает должным образом
следующий контроллер работает без проблем.
app.controller('foo', ['$scope',function ($scope) {
$scope.delete = function(){
bar($scope);
}
}]);
Я попытался сделать его немного чище, используя bind
:
app.controller('foo', ['$scope',function ($scope) {
$scope.delete = bar.bind(null, $scope);
}]);
к сожалению, эта форма не работает, как ожидалось и $scope
всегда поставляется со старой версией $scope в связанном методе (bar
здесь), даже после изменения $ scope для ссылки на другое значение. Что с ним не так?
что еще?
если я не должен использовать bind
здесь, какова альтернатива?
5 ответов
я предполагаю, что ваша проблема в том, что ваша граница Util.bar
всегда поставляется со старой версией $scope
, даже после $scope
изменилось, чтобы ссылаться на другое значение.
bind
персонализация значения, а не переменные. Вы связываете текущее значение $scope
to Util.bar
. С другой стороны, ваш первый стиль заставляет идентификатор $scope
быть разрешенным к значению (или, действительно, записи переменной внешней области) каждый раз, когда функция работает.
если $scope
изменения чтобы ссылаться на совершенно другое значение, необходимо использовать первую форму. .bind(null, $scope)
решить $scope
значение сразу и использовать это значение навсегда, в то время как первая форма без bind
решить $scope
до значения при каждом запуске функции.
посмотри Plunker .
$scope.delete1 = function(){
bar($scope);
};
$scope.delete2 = bar.bind(null, $scope);
$scope.delete3 = function(){
bar(this);
};
Мне кажется, что он ведет себя точно так, как должен: delete1 и delete2, похоже, делают то же самое на родительском и дочернем контроллере. Delete 3 ведет себя по - другому-причина объясняется очень красиво в этом ответе:контроллер
возможно, вы можете точно указать, какое поведение (usecase) вы найдете неправильным. Ссылки возврата назад таковы, что вы можете оставить страницу контроллера, а затем вернитесь к новому экземпляру контроллера (и новой области-как вы можете видеть из $scope.$идентификатор.)
вы уверены bar
не использует ничего из Util
? Этого:
app.controller('foo', ['$scope',function ($scope) {
$scope.delete = Util.bar.bind(Util, $scope);
}]);
Как упоминалось в ответе apsillers выше, метод bind немедленно оценивается при назначении - поэтому текущее значение $scope связано как аргумент для передачи функции bar. Что касается "более чистой" альтернативы, я не понимаю, почему вам нужно что-то "более чистое": вы хотите назначить $scope.удалить как функцию, которая вызывает bar с текущим значением $ scope, которое ваш текущий код делает с T. Если вы все еще ищете что-то немного более скудный код, вы всегда можете принять синтаксис ES6 fat arrow (но вам понадобится транспилер, такой как babel) - так что ваш код будет выглядеть так:
app.controller('foo', ['$scope',function ($scope) {
$scope.delete = () => bar($scope);
}]);
Как сказал @apsillers, в bind $scope разрешается и используется в последующих вызовах,поэтому более чистый способ является первым, но все же, если вы хотите использовать bind, используйте
app.controller('foo', ['$scope',function ($scope) {
$scope.delete = function(){
bar.bind(null, $scope);
}
}]);