Подтвердить что ты не робот

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, или я чего-то не хватает?

4b9b3361

Ответ 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];
}

Причина, по которой я делаю это, заключается в том, что мы хотим, чтобы контроллеры были максимально чистыми и имели все наши данные в одном централизованном месте. Также должно быть показано большинство данных в службе.