Хорошо, так что готовьтесь, потому что это очень сложная концепция , чтобы понять.
У вас есть живое демо здесь:
https://stackblitz.com/edit/angular-2kxtzs?file=src%2Fapp%2Fhello.component.ts
Для кода:
import { Component, Input, Output, EventEmitter } from '@angular/core';
const Expose: (methods: string[]) => ClassDecorator = (methods) => {
return component => {
for (const method of methods) {
const eventEmitterName = `${method}Emitter`;
component.prototype[eventEmitterName] = new EventEmitter();
const outputFactory = Output(method);
const orgFn = component.prototype[method];
component.prototype[method] = (...args) => {
orgFn(...args);
component.prototype[eventEmitterName].emit();
}
outputFactory(component.prototype, eventEmitterName);
}
}
}
@Component({
selector: 'hello',
template: ``,
styles: [`h1 { font-family: Lato; }`]
})
@Expose(['open'])
export class HelloComponent {
@Input() name: string;
open() {
console.log('Clicked on the button, now emitting an event');
}
ngOnInit() {}
}
Декораторы классов являются функциями.
В вашем случае это фабрика декораторов классов: вы предоставляете параметры, и она должна возвращать декоратор классов. Вот подпись, которую вы можете видеть:
const Expose: (methods: string[]) => ClassDecorator = (methods) => { ... }
Он объявляет Expose
фабрикой, которая возвращает Class Decorator. Ваша фабрика принимает список методов в качестве параметров.
Теперь эта фабрика должна вернуть декоратор класса. Декоратор класса - это функция, у которой сам компонент является единственным параметром. Это строка
return component => { ... }
Возвращает функцию, соответствующую подписи ClassDecorator
.
После этого вам нужно переписать каждый из ваших методов. Таким образом, вы будете зацикливать их с помощью простого цикла.
В цикле мы создадим новый источник событий. Для простоты мы будем использовать имя [method]Emitter
. Итак, начнем с создания святого имени:
const eventEmitterName = `${method}Emitter`;
Как только это будет сделано, мы свяжем его с прототипом компонента:
component.prototype[eventEmitterName] = new EventEmitter();
Теперь у вас есть источник событий.
После этого вам нужно будет привязать к нему выходной декоратор. Если вы выполните первые шаги, вы поймете, что Output
на самом деле тоже фабрика. Это означает, что она возвращает функцию MethodDecorator
, чья подпись
(component, methodKey) => { ... }
(есть третий параметр, называемый дескриптором, но он вам не нужен, поэтому я его проигнорирую).
Как только это станет известно, мы возьмем наш заводской результат для нашего метода:
const outputFactory = Output(method);
Это создаст вывод с именем вашего метода (здесь это open
).
Как только это будет сделано, мы переопределим данный метод для генерации события, когда его обработка будет завершена.
Это базовая переопределение функции JS:
const orgFn = component.prototype[method];
component.prototype[method] = (...args) => {
orgFn(...args);
component.prototype[eventEmitterName].emit();
}
В последней строке мы отправляем событие через ранее созданный источник событий.
Теперь все, что нам осталось сделать, это привязать этот источник событий к нашему компоненту. Для этого мы просто вызываем метод декоратор, созданный фабрикой выходных данных.
outputFactory(component.prototype, eventEmitterName);
Теперь ваш декоратор готов и работает. Как видно из стекаблица, код в функции open
запускается, а затем запускается и запускается код для вывода (open)
в шаблоне компонента приложения.
И Вуаля!
Я сделал бы подвеб-проекты. Каждый веб-сайт является подпроектом родительского веб-сайта. Можно записать HttpModule, который проверяет некоторое хранилище данных, чтобы видеть, есть ли у того клиента доступ на тот сайт (модуль), и запретите доступа таким образом. У Scott Guthrie есть хорошее сообщение о том, как настроить sub веб-проекты здесь.
Один простой способ сделать это должно было бы просто использовать SiteMap. Можно выделять aspx файлы и скомпилировать другой dll's все, что Вы хотите. SiteMap абсолютно независим и может быть настроен однако, Вы хотите включать безотносительно модулей, которые Вы хотите с любыми полномочиями, которые Вы хотите. Нет никакой реальной потребности ни в каких модулях кода для регистрации себя в других модулях кода. Это - ASP.NET, каждый запрос независим и может запуститься в любой aspx точке входа. Что касается Ваших страниц, добавление функциональности перекрестного модуля так же просто как обеспечение ссылки на страницу в другом модуле. SiteMap выполняет это ловко.