У меня есть директива под названием NgtsAjax
, директива делает запрос Ajax к URL передается на path
атрибута, вы можете использовать этот способ:Нужна помощь миграции директивы Angular2
<ngts-ajax path="/api/customer/{{customerId}}" as="customer" on-success="ctrl.load(customer)" />
директивы заводом является:
function NgtsAjaxFactory() {
return {
restrict: "E",
bindToController: true,
scope: {
url: "@path",
as: "=as",
httpVerb: "@verb",
onFail: "&onFail",
onSuccess: "&onSuccess"
},
controller: NgtsAjax,
priority: 20000
}
}
Директива использует атрибут path
, привязанный к url
, особым образом. Я объясню это.
я получаю значение url
и обнаружить, если имеют параметров с использованием синтаксиса усов, если использует его я получаю каждый параметр и я держу в списке параметров называется pathVariables
, по последнему я наблюдаю атрибут path
для изменений, когда path
является изменено. Я проверяю, имеет ли значение каждый параметр в pathVariables
, и все они имеют значения и используют $ http для запуска запроса ajax.
Это соответствующие фрагменты кода контроллера:
class NgtsAjax {
//... class attributes
//...
constructor($scope, private $interpolate, private $attrs, ....)
this.pathAttr = $attrs.path;
....
....
this.parentScope = $scope.$parent;
this.observePath();
}
private observePath() {
if (!this.url)
this.url = this.$location.path();
this.pathVariables = [];
else {
// Gets variables in path attribute
const pathVariables = this.pathVariables = this.pathAttr.match(/{{[\w.\s|:$']+}}/g) || [];
if (pathVariables) {
for (let i = 0; i < pathVariables.length; i++) {
pathVariables[i] = pathVariables[i].toString();
}
}
}
this.$attrs.$observe("path",() => {
if (this.pathVariablesHaveValues())
this.run();
});
}
private pathVariablesHaveValues() {
let result = true;
const pathVariables = this.pathVariables;
for (let i = 0; i < pathVariables.length; i++) {
const interpolation = pathVariables[i];
const expression = this.$interpolate(interpolation);
if (!expression(this.parentScope)) {
result = false;
break;
}
}
return result;
}
}
я сделать это таким образом, потому что атрибут путь может иметь несколько переменных/выражений, например:
<input type="text" ng-model="model.customerId"/>
<input type="text" ng-model="model.invoiceId"/>
<ngts-ajax path="/api/customer/{{model.customerId}}/invoice/{{model.invoiceId}}" as="customerInvoice" on-success="ctrl.load(customerInvoice)" />
Для того, чтобы сделать ajax-запрос Я должен быть уверен, что customerId
и invoiceId
имеют значения.
Вы можете посмотреть полный исходный код директивы here.
Тогда я не уверен, как подойти к реализации этого, я не уверен, что это должен быть @Directive или @Component, и я не знаю, как решить проблему с переменными на путь.
Как вы думаете, это лучший подход?
Обновление 1: Вопрос не в том, что использование Директивы или Компонента ... проблема заключается в том, что поведение атрибута path
.
Обновление 2: Средство/взлом/исправление/... решение.
У меня вставить небольшое ограничение, чтобы сделать его работу я заставляю писать переменные на path
квадратные скобки ([]) таким образом:
<em-ajax path="/api/customer/[{{model?.customerId}}]/invoice/[{{model?.invoiceId}}]"></em-ajax>
С этим я могу детерминированный, если переменные пустые ищем "[]".
Я определил директиву так:
@Directive({
selector: "em-ajax",
})
export class EmAjax implements OnChanges {
@Input() path : string;
...
...
ngOnChanges() {
if (this.pathIsValid()) {
this.run();
}
}
pathIsValid() {
if (this.path.indexOf("[]") >= 0) {
return false;
}
return true;
}
run(params? : any) {
let path = this.path.replace("[", "").replace("]", "");
// `path` is the real url
// I can launch http request
}
...
...
}
Если вы знаете другой способ сделать это лучше, дайте мне знать;)
Хорошо, но реальной проблемой является поведение с атрибутом path. –
Не знаете, в чем проблема. Возможно, вы хотите сделать ввод setter '@Input() set path (value: string) {...}' для выполнения некоторого кода при обновлении значения или реализации 'ngOnChanges()', который вызывается, когда входное значение изменения. –