AngularJS 在 $http 响应返回后执行链接功能 [英] AngularJS do link function after $http response returned

查看:26
本文介绍了AngularJS 在 $http 响应返回后执行链接功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我需要在 http 响应返回后在指令中执行链接功能.这个想法是这样的:

I need to perform a link function in a directive after an http response returns. The idea is something like this:

<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 完成之前运行:实际序列是

Here, I need to bind the input field to an element of the response, but I don't know what the element will be called until I get the response. But when I run it, the directive's link runs before $http gets done: the actual sequence is

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

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

I'm somewhat familiar with $q, but am not sure how that would be used to do what needs to be done. BTW, I have shown only one input field invoking the myField directive, but there are potentially many of them on the page, and they all need the same information.

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

Edited to add more information in response to request:

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

I have a service that returns a JSON data structure. I do not know in advance exactly what that data structure will look like, but I can figure it out and match the fields up with my page's input fields. I'm attempting to do this matching up in the link function. I'm glad to do it somewhere else; I could do it in the $http.success function, but that would be doing DOM manipulation in a controller; and my understanding is that DOM manipulation should only be done in a directive.

这是我的 HTML 需要的样子:

Here's what my HTML needs to look like:

<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">

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

The response from the server will be something like:

{
    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" }
        ]
      }
    ]
 }

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

The server's response may vary because:

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

这里的整个问题是我想将 "[MY_EXTENSION_NAME]myFieldName" 转换为 ng-model "model.extensions[0].fields[0].value.但是,我现在正在考虑将数据转换为规范的阅读时的表格会更容易,所以ng-model可以只是model.my_extension_name.myFieldName".

The whole problem here is I want to convert "[MY_EXTENSION_NAME]myFieldName" into the ng-model "model.extensions[0].fields[0].value. However, I am now thinking transforming the data into a canonical form during reading will be easier, so ng-model can just be "model.my_extension_name.myFieldName".

推荐答案

目前尚不清楚您要实现的目标(我很确定会有更好的方法),但您可以这样做:

It is not clear what you are trying to achieve (I'm pretty sure there will be some better way), but you could do it like this:

1.
在您的范围内定义承诺:

1.
Define a promise in your scope:

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 中,引用该承诺以将其传递给您的指令:

2.
From your HTML, reference that promise in order to pass it to your directive:

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

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

3.
Get this promise into your directive's isolate scope:

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

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

4.
In your link function, register a callback for when the promise gets resolved (i.e. you get a response to your request) and do all necessary manipulation:

...
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);
    });
}

<小时>

另请参阅此简短演示.

这篇关于AngularJS 在 $http 响应返回后执行链接功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆