Я работаю над проектом, в котором клиент должен иметь возможность изменять каждую и любую строку, которые мы использовали в приложении. Эта потребность аналогична потребностям i18n, за исключением того, что то, что мы, команда разработчиков, предоставило и набор строк, которые клиент может завершить после их модификаций, находятся на одном языке.
Поэтому я реализовал фильтр, так что строки в html-представлениях записываются как {{'one.code.on.view1' | label }}
выражение, такое как {{'one.code.on.view1' | label }}
{{'one.code.on.view1' | label }}
. Фильтр полагается на услугу, которая, так сказать, "хранит весь набор меток в памяти".
Я разработал простой пользовательский интерфейс для изменения текстовых меток: все ярлыки показаны в угловой-ui-сетке. Каждая строка имеет (не изменяемый) код и (модифицируемую) метку. Используя функцию редактирования встроенной сетки, я сохраняю измененную метку в базе данных. Все идет нормально.
Моя проблема заключается в том, что при сохранении измененной метки в базе данных я также обновляю запись этого ярлыка в службе, которая "хранит метки", но, к сожалению, в случае, если измененная метка была отображена на экране, старое значение не обновляется.
Мой вопрос: как я могу инициировать оценку привязок на представлении? Я использовал каждый трюк $ timeout или $ apply, который я знал, но безрезультатно, что не удивительно, поскольку весь код работает в контекстах Angular.
Вот код фильтра и сервиса: (для ясности "libellé" - это французское слово "label", хотя мы иногда неправильно используем "label", а "scoop" - это название проекта, следовательно его использование в качестве префикса)
function scoopLabelSceFn($resource, $rootScope, $timeout) {
var rest = $resource('admin/libelle/list', {}, {});
var labels = [];
function loadAllLabels() {
labels = rest.query({}, function(result) {
var liste = [];
for (var idx = 0; idx < result.length; ++idx) {
var entry = result[idx];
liste[entry.code] = entry.libelle;
}
labels = liste;
});
}
loadAllLabels();
return {
getLabels : function() {
return labels;
},
reloadLabels : function() {
loadAllLabels();
},
updateLabel : function(code, newValue) {
labels[code] = newValue;
}
};
}
function scoopLabelFilterFn($log, scoopLabelService) {
return function(input) {
if (angular.isString(input)) {
var libelles = scoopLabelService.getLabels();
var res = libelles[input];
if (res) {
return res;
}
$log.log("scoopLabelFilter: no entry for: " + input);
return input;
}
$log.log("scoopLabelFilter: incorrect parameter type");
return "";
};
}
module.filter("label", [ "$log", "scoopLabelService", scoopLabelFilterFn ]);
module.factory("scoopLabelService", [ "$resource", "$rootScope", "$timeout", scoopLabelSceFn ]);
На самом деле, нет ничего принципиально неправильного в коде.
Похоже, что фильтры Angular Treats поменялись где-то на ветке 1.3.x. Как следствие, код, возвращающий функцию фильтра, должен быть изменен.
Старый код:
return function(input) {
...
Измененный код:
function filterFn(input) {
...
filterFn.$stateful = true;
return filterFn;
При этом все выражения, относящиеся к фильтру, автоматически переоцениваются.