AngularJS, этот способ использования сервиса хорошо?
У меня этот HTML:
<p>Hello {{name}}</p>
и контроллер:
function myCtrl(scope, service) {
scope.name = service.getUsername(); // service.getUsername() return "World!"
}
myCtrl.$inject = ['$scope', 'originalService'];
Служба работает нормально, поэтому я не вставляю код здесь...
В этом случае результат " Hello world!"
Я изменил HTML таким образом:
<p>Hello {{service.getUsername()}}</p>
Но это не сработает.
Я сменил контроллер:
function myCtrl(scope, service) {
scope.ser = service;
}
myCtrl.$inject = ['$scope', 'originalService'];
а затем HTML
<p>Hello {{ser.getUsername();}}</p>
Это работает!
Итак, мой вопрос:
Является ли это единственным способом использования функций службы непосредственно в HTML, или я чего-то не хватает?
Ответы
Ответ 1
Шаблоны AngularJS могут вызывать только функции, доступные в области. Итак, какой бы подход вы ни выбрали, вам нужно иметь свою функцию в области.
Если вы хотите, чтобы ваши сервисные функции были напрямую вызваны из шаблона, у вас есть несколько вариантов:
Тот, который вы пробовали - то есть, выведите всю службу в области:
$scope.service = service;
а затем в шаблоне:
<p>Hello {{service.getUsername();}}</p>
Это однострочный элемент в контроллере и предоставляет все методы обслуживания в области видимости и, следовательно, шаблоны.
Выставлять методы по одному
иметь точный контроль над тем, что подвергается воздействию:
$scope.getUsername = service.getUsername;
а затем в шаблоне:
<p>Hello {{getUsername();}}</p>
Для этого требуется больше методов раскрытия работы, но дает вам мелкомасштабный контроль над тем, что открывается.
Использовать методы проксирования:
$scope.getMyUsername = function() {
//pre/post processing if needed
return service.getUsername();
};
Вы можете использовать любой из этих методов или смешивать и комбинировать их, но в конце дня функция должна заканчиваться в области (либо напрямую, либо через другой объект, открытый в области).
Ответ 2
Другой способ сделать это:
Открыть службу на $rootScope:
$rootScope.service = service;
а затем в шаблоне:
<p>Hello {{service.getUsername();}}</p>
Вы можете сделать это на app.run, и вы получите услугу во всех представлениях вашего приложения. Вы можете использовать этот метод для служб аутентификации.
Ответ 3
Другим способом разоблачения вашей службы в пределах области $будет добавление указателя на объект службы/объект данных.
scope.serviceData = service.data;
// Or
scope.getServiceData = service.getData;
В вашем представлении вы можете вызвать его с помощью круглых скобок.
<input ng-model="serviceData().key" />
// Or
<input ng-model="getServiceData().key" />
// Or
{{getServiceData().key}}
Мне лично нравится этот подход, и я в настоящее время его использую, чтобы синхронизировать несколько представлений с одними и теми же данными. Это вызывает некоторые проблемы, хотя, как объясняется здесь:
AngularJS. Лучшая практика в отношении правильного привязки данных по двум каналам из службы
Что касается отображения большого количества данных, я в настоящее время пытаюсь сделать что-то вроде этого.
// Within your view.
{{getServiceDataByKey('key')}}
// In your controller.
scope.getServiceDataByKey = service.getServiceDataByKey;
// In your service.
getServiceDataByKey : function (key) {
return dataObject[key];
}
Причина, по которой я делаю это, заключается в том, что мы хотим, чтобы контроллеры были максимально чистыми и имели все наши данные в одном централизованном месте. Также должно быть показано большинство данных в службе.