AngularJs 在指令中操作来自服务响应的数据

AngularJs Manipulate data from service response in directives

本文关键字:服务 响应 数据 指令 操作 AngularJs      更新时间:2023-09-26

我从我的服务中得到了一些回应。响应的形式是

 "My data <my-tag>Click me</my-tag>".

响应包含标记"my-tag"。我想编写一个指令,每当呈现响应时,该指令都会操纵标签中的内容"单击我"。自定义标记中的内容应转换为超链接。我该怎么做?这是我的示例代码。

我有我的服务.js

服务.js

(function() {
    function myService() {
        this.getData = function(question,questionType) {
        anotherService.getList(function(data, status) {   
 //Here data.text = "<my-tag>Click me</my-tag>"            
                   document.getElementById("additionalData").innerHTML + data.text;
            });                         
        }                           
    }
    app.addService(app.config.modules.MY_MODULE, "myService", myService);
}());

指令.js

(function() {
    app.directive('myTag', function () {
        debugger;
        return {
            link: function ($scope, element, attrs) {
                debugger;
                //Convert the text "Click me" into hyperlink
            }
        };
    });
}());

我的网页.html

<html ng-app = "myApp">
        <head>
            <script>
                app.inject(app.config.modules.MY_MODULE, "myService", function(instance) {
                    myService = instance;
                    console.log("myService dependency injected successfully.");
                });
            </script>
        </head>
        <body ng-controller="myCtrl">
            <div>
                <img id="getList" onclick="myService.getData()">
            </div>
        </body>
    </html>
您需要

将收到的响应编译为文本以使myTag正常工作,否则根本不会调用link myTag函数。

一般的想法应该是避免直接操作 DOM,并将此任务留给指令。因此,渲染之后的一些数据的最佳方法是修改模型(scope)并对应用于应包含要渲染数据的元素的指令中的这些更改做出反应。

以下是可能的解决方案之一:

.HTML

<!DOCTYPE html>
<html ng-app="app">
  <head>
    <script data-require="angular.js@1.5.3" data-semver="1.5.3" src="https://ajax.googleapis.com/ajax/libs/angularjs/1.5.3/angular.min.js"></script>
    <link rel="stylesheet" href="style.css" />
    <script src="script.js"></script>
  </head>
  <body>
    <h1>Hello Plunker!</h1>
    <my-list></my-list>
  </body>
</html>

JavaScript

angular.module('app', [])
  .directive('myTag', function() {
    return {
      transclude: true,
      template: '<a href="#" ng-transclude></a>'
    }
  })
  .directive('myList', ['$compile', function($compile) {
    return {
      template: '<ul></ul>',
      link: function(scope, element) {
        scope.$watchCollection('data', function(data) {
            if(data && data.length) { 
              element.empty(); 
              data.forEach(function(item) {
                element.append( 
                  $compile( // <= in order to make myTag directive work, you need to compile text
                    angular.element('<p>'+item+'</p>').contents() // convert text to list of DOM elements wrapped by jqLite/jQuery
                  )(scope)
                );
              });
            }
          }
        );
      }
    }
  }])
  .run(['$http', '$rootScope', function($http, $rootScope) {
    $rootScope.data = []; 
    $http.get('data.txt').then(function(xhr) { 
      $rootScope.data.push(xhr.data);
    });
  }]);

普伦克

https://plnkr.co/edit/VOl8P7r2DpnayMjRWbvI?p=preview