Где живет пользовательский экземпляр канала? Как код компонента может получить доступ к экземпляру пользовательского канала, используемому в его HTML?
У меня есть пользовательский канал, который я использую в части HTML компонента. В модуле объявлено:
declarations: [ I18nPipe ],
Я хочу иметь возможность вызывать метод из кода компонента (не transform
метод).
Я надеялся, что экземпляр канала живет где-то в контексте внедрения зависимостей, чтобы я мог получить его. Но я был неправ. Если я вставлю его в конструктор компонента (например, в любой обычный сервис):
constructor(private i18nPipe: I18nPipe)
тогда я получил ошибку: нет поставщиков. Поэтому я включаю его в providers
раздел того же модуля:
providers: [ I18nPipe ]
тогда у меня будет доступ к нему в коде компонента, но будет два экземпляра моего пользовательского канала.
создано
providers
, доступно в контексте DI. Я получу этот экземпляр при внедрении в конструктор, поэтому я буду работать с этим экземпляром в коде моего компонента.экземпляр, который используется в HTML. Где оно живет? Я хочу получить доступ к этому экземпляру в коде моего компонента, а не к "предоставленному"; как я могу получить это?
1 ответ
Каждый угловой компонент компилируется в представление с узлами. И трубы являются одним из типов узлов. И вы не можете внедрить узлы вида, кроме родительских компонентов и директив, определенных в элементе host компонента.
Предположим, у вас есть следующий шаблон для компонента:
<div>{{3|mypipe}}</div>
У вас будут следующие узлы просмотра:
PipeElement
HTMLDivElement
HTMLTextElement
Затем во время обнаружения изменений Angular проходит через каждый узел и выполняет определенное действие по обнаружению изменений - обновление dom, обновление привязок или transform
вызов метода.
Если вы хотите, вы можете получить доступ к экземпляру канала через экземпляр View (который не является публичным API) следующим образом:
class I18nPipe {
sayHello() {}
}
class ComponentWithPipe {
constructor(cd: ChangeDetectorRef) {
setTimeout(() => {
const pipeNode = cd._view.nodes.find((n) => {
return n.instance && n.instance instanceof I18nPipe
});
const pipeInstance = pipeNode.instance;
pipeInstance.sayHello();
})
}
Но это только для образовательных целей. Вы не хотите использовать этот подход в производстве.
Вот несколько статей, которые помогут вам понять: