$ injector.instantiate VS $injector.get VS $инжектор.инвук в угловых

В чем разница между $injector.instantiate, $injector.get и $injector.invoke в AngularJS?

Ответ 1

Учитывая следующую услугу:

app.service('myService', function ($q, $http) {
  return {
    q:    $q,
    http: $http
  };
});

$injector.get(name, [caller]);

Возвращает экземпляр запрашиваемой службы.

$injector.get('myService');
// { q: $q, http: $http }

$injector.invoke(fn, [self], [locals]);

Вызывается предоставленный метод и проходит по заданным аргументам из $injector.

$injector.invoke(function (myService, $http) {
  console.log(myService); // { q: $q, http: $http };
  console.log(this);      // { v: 'im this!' };
  console.log($http);     // null
}, { v: 'im this!' }, { $http: null });

$injector.instantiate(Тип, [locals]);

Создает новый экземпляр данного типа. Выполняет функцию конструктора, а затем вызывает новый экземпляр с аргументами, указанными в аннотации конструктора.

Предположим, что следующий класс:

function Person (fName, lName, $http, $q) {
  return {
    first_name: fName,
    last_name:  lName,
    http: $http,
    q:    $q
  }
}

Теперь, если бы мы хотели создать новое Person в нашем контроллере, мы могли бы сделать это следующим образом:

app.controller('...', function ($injector) {
  var $http = $injector.get('$http');
  var $q    = $injector.get('$q');
  var p     = new Person('kasper', 'lewau', $http, $q);

  console.log(p); // { first_name: 'kasper', last_name: 'lewau', http: $http, q: $q };
});

Представьте, что Person имеет ~ 20 или около того зависимостей, и мы извлекали каждый из них методом $injector.get.

обременительно! И - вам нужно будет синхронизировать ваши параметры и аргументы. тьфу.

Вместо этого вы можете сделать это:

app.controller('...', function ($injector) {
  var p = $injector.instantiate(Person, {
    fName: 'kasper',
    lName: 'lewau'
  });
  console.log(p); // { first_name: 'kasper', last_name: 'lewau', http: $http, q: $q };
});

И - если бы мы захотели, мы могли бы предоставить locals для вызова .instantiate, чтобы переопределить то, что обычно будет иметь внутренний $injector.get() при создании экземпляра.

var p = $injector.instantiate(Person, {
  fName: 'kasper',
  lName: 'lewau'
}, { $http: 'Nothing!', $q: 'Nothing!' });
console.log(p); // { first_name: 'kasper', last_name: 'lewau', http: 'Nothing!', q: 'Nothing!' };

Надеюсь, это объяснит разницу между тремя. Если вам нужна дополнительная информация об их различиях, я бы рекомендовал следующие статьи:

Ответ 2

Дополнительные отметки к Kasper Lewau отвечают, потому что я не могу добавлять комментарии.

$injector.invoke(fn, [self], [locals], [serviceName]);

  • Может использоваться для любой функции: конструктор класса или нет (он автоматически проверяет внутри) Параметр
  • ' Self' используется только для чистой функции.

$injector.instantiate(Тип, [locals]);

  • Должен использоваться только для конструкторов классов, или он будет строить пустой объект {}