Ответ 1
РЕДАКТИРОВАТЬ: пожалуйста, перейдите прямо к нижней части ответа, чтобы получить лучшую версию; ответ в хронологическом порядке; Я получил оптимальный код после нескольких итераций, в конце. Спасибо.
- Могу ли я переопределить поведение ng-bind или украсить его по умолчанию?
Да. Я сделал очень простую реализацию, которая позволяет ng-bind
вести себя так, как вы хотите. Ну... Я не уверен, что это именно то, что вы хотите, но, по крайней мере, оно делает то, что я понял, вы хотите.
Рабочая скрипка: http://jsfiddle.net/93QQM/
И вот код:
module.directive('ngBind', function() {
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind = 'myBind(' + tAttrs.ngBind + ')';
return {
pre: function(scope) {
scope.myBind = function(text) {
return angular.element('<div>' + text + '</div>').text();
}
}
};
}
}
});
Это не совсем "дополнительная директива" - это способ "переопределить поведение ng-bind". Он не добавляет новую директиву, он просто расширяет поведение существующей директивы ngBind.
В функции компилировать мы модифицируем значение атрибута ng-bind
, завершая его в вызов функции. При этом у нас есть доступ к исходной стоимости модели и возможность ее изменения.
Мы делаем функцию доступной через область на этапе предварительной привязки, потому что, если мы это сделаем на фазе постсвязывания, функция будет доступна только после, которую восстановила исходная директива ngBind значение из атрибута (которое будет пустой строкой, потому что функция wil не найдена).
Функция myBind
проста и умна: она создает элемент, а текст используется без изменений - как тело элемента, только для немедленного получения через функцию text
, которая возвращает содержимое так же, как и "браузер отображает" его.
Таким образом, вы можете использовать ngBind, как обычно, например <div ng-bind="model.content" />
, но иметь это измененное поведение.
Улучшенная версия
Вместо прикрепления функции myBind
к каждой области применения, где применяется ngBind, на каждой фазе предварительной привязки мы можем привязать ее только один раз к $rootScope
, что делает ее сразу доступной для всех областей.
Новая рабочая скрипка: http://jsfiddle.net/EUqP9/
Новый код:
module.directive('ngBind', ['$rootScope', function($rootScope) {
$rootScope.myBind = function(text) {
return angular.element('<div>' + text + '</div>').text();
};
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind = 'myBind(' + tAttrs.ngBind + ')';
}
};
}]);
Гораздо чище, чем предыдущая версия! Конечно, вы можете изменить имя функции myBind
на любое другое имя, которое вы хотите. "Стоимость" функции такова: добавьте эту простую функцию в корневую область - вам решать, стоит ли цена.
Еще одна версия
Под влиянием Chemiv ответ... почему бы не удалить функцию из какой-либо области и не сделать ее фильтром? Он также работает.
Еще одна новая рабочая скрипка: http://jsfiddle.net/hQJaZ/
И новый код:
module.filter('decode', function() {
return function(text) {
return angular.element('<div>' + text + '</div>').text();
};
}).directive('ngBind', function() {
return {
compile: function(tElement, tAttrs) {
tAttrs.ngBind += '|decode';
}
};
});
Теперь у вас есть три варианта выбора из меню.