AngularJS在$http响应返回后执行链接功能



在http响应返回后,我需要在指令中执行链接函数。这个想法是这样的:

<input type="text" my-field>
<script>
angular.module("mine")
.controller ('myCtrl', function ($scope) {
$http.get("/my/service").success(function (data, status, headers, config) {
// OK, done with the query... now I know my field name to bind to. Somehow
// I have to get it down to the link function below...
});
})
.directive ('myField', function ($compile) {
return {
link: function (scope, element, attrs) {
var my_field = attrs.myField;
element.removeAttr('my-field');
// Somehow figure out the field here in ngFieldSpec
element.attr('ng-model', ngFieldSpec);
$compile(element)(scope);
};
});
</script>

在这里,我需要将输入字段绑定到响应的一个元素,但在得到响应之前,我不知道该元素将被调用什么。但当我运行它时,指令的链接在$http完成之前运行:实际的序列是

  • $http.get启动
  • 指令的链接函数运行
  • $http.get返回成功

我对$q有点熟悉,但不确定如何使用它来做需要做的事情。顺便说一句,我只显示了一个调用myField指令的输入字段,但页面上可能有很多输入字段,它们都需要相同的信息。

编辑以添加更多信息以响应请求:

我有一个返回JSON数据结构的服务。我事先不知道数据结构会是什么样子,但我可以弄清楚,并将字段与页面的输入字段进行匹配。我正在尝试在链接函数中进行匹配。我很高兴在别的地方做这件事;我可以在$http.success函数中完成,但那将是在控制器中进行DOM操作;我的理解是DOM操作只能在指令中完成。

以下是我的HTML需要的样子:

<input type="text" my-field="[MY_EXTENSION_NAME]myFieldName">
<input type="text" my-field="[MY_EXTENSION_NAME]myFieldName2">
<input type="text" my-field="[MY_EXTENSION_NAME_2]myFieldName">

来自服务器的响应将类似于:

{
realField1: "Diddly",
realField2: "Squat",
extensions: [
{
name: "MY_EXTENSION_NAME",
fields: [
{ name="myFieldName" value="Foo" },
{ name="myFieldName2" value="Bar" }
]
},
{
name: "MY_EXTENSION_NAME_2",
fields: [
{ name="myFieldName" value="Baz" },
{ name="myFieldName2" value="Buz" }
]
}
]
}

服务器的响应可能会有所不同,因为:

  • 可能有任意数量的扩展("MY_EXTENSION_NAME"等)
  • 延期可以按任何顺序退回
  • 可以有任意数量的字段
  • 字段可以按任何顺序返回

这里的全部问题是我想将"[MY_EXTENSION_NAME]myFieldName"转换为ng模型"model.extensions[0].fields[0].value"。然而,我现在认为在读取过程中将数据转换为规范形式会更容易,因此ng模型可以只是"model.MY_EXTENSION_NAME.myFieldName"。

目前还不清楚你想要实现什么(我相信会有更好的方法),但你可以这样做:

1.
在您的范围中定义一个承诺:

app.controller('myCtrl', function ($http, $scope) {
$scope.model = {
promise: $http.get('/my/service'),
myField01: 'Hello, world, from 01 !',
myField02: 'Hello, world, from 02 !',
myField03: 'Hello, world, form 03 !'
};
});

2.
从HTML中,引用该承诺以便将其传递给您的指令:

<input type="text" my-field="model.promise" />

3.
将此承诺纳入指令的隔离范围:

app.directive ('myField', function ($compile) {
return {
scope: { promise: '=myField' },
...

4.
link函数中,注册一个回调,以确定承诺何时得到解决(即您得到了对请求的响应),并执行所有必要的操作:

...
link: function (scope, elem, attrs) {
scope.promise.success(function (data) {
elem.removeAttr('my-field');
elem.attr('ng-model', 'model.' + data.fieldName);
$compile(elem)(scope.$parent);
});
}

另请参阅此简短演示

最新更新