绑定Angularjs到新创建的html元素动态 [英] Bind Angularjs to newly created html element dynamically

查看:131
本文介绍了绑定Angularjs到新创建的html元素动态的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有,一旦随叫随到点击的服务来回报一些数据多个选项卡标签页。一些数据返回HTML形式,非常随意。我想收集被输入的那些值和经由服务发送数据返回给服务器。我的问题是,我无法从我动态创建的HTML输入元素获取数据。

我创建了一个 Plunker 表明问题是什么。请注意,HTML值可以在任何时候改变,因此硬编码的HTML将无法工作。在这里,从plunker的code,但请看plunker为怎么回事的最佳视角。

app.js

  VAR应用= angular.module('plunker',[]);app.controller('MainCtrl',函数($范围,SCE $,$编译){
    $ scope.name ='世界';
    $ scope.html =;    $ scope.htmlElement =功能(){
        VAR HTML =<输入类型='文本'NG-模式='HTML'>< /输入>中;
        返回$ sce.trustAsHtml(HTML);
    }});

的index.html

 <!DOCTYPE HTML>
< HTML NG-应用=plunker>  < HEAD>
    <间的charset =UTF-8/>
    <标题> AngularJS Plunker< /标题>
    <脚本>的document.write('<基本href =+ document.location +'/>');< / SCRIPT>
    <链接rel =stylesheet属性HREF =style.css文件/>
    &所述; SCRIPT SRC =htt​​ps://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.js>&下; /脚本>
    &所述; SCRIPT SRC =app.js>&下; /脚本>
  < /头>  <机身NG控制器=MainCtrl>
    < P>您好{{名}}<!/ P>    < D​​IV NG绑定-HTML =HTML元素()>< / DIV>    {{HTML}}  < /身体GT;< / HTML>


解决方案

一个解决方案是使用ngInclude以$ templateCache,如本的 Plunker

有几件事情要注意。

首先,你可以使用服务这里获取您的模板,并将其添加到$ templateCache,描述 (例如复制):

  myApp.service('myTemplateService',['$ HTTP,$ templateCache',函数($ HTTP,$ templateCache){
  $ HTTP(/ * ... * /)。然后(功能(结果){
    $ templateCache.put(我的动态模板,结果);
  });
}]);

然后你可以将其包含在您的模板如下:

 < D​​IV NG-包括='我的动态模板'>< / DIV>

ngInclude将允许在HTML字符串数据绑定,所以你不需要ngBindHtml。

第二个问题是,作为ngInclude创建一个新的范围,访问新建范围,除非你通过一个对象来访问它不能正常工作之外的 HTML 属性父范围(如 NG-模式=data.html而不是 NG-模式=HTML 。注意, $ scope.data = {} 父范围是什么使得在这种情况下ngInclude范围的HTML以外访问。

(见这个答案了解为什么你应该总是使用在ngModels一个点。)


修改

正如你指出的那样,使用服务时,返回的HTML ngInclude选项是有用的要少得多。

下面是编辑过的 plunker 与使用$编译基于指令的解决方案,如在大卫的上述评论。

相关加法:

  app.directive('customHtml',函数($编译,$ HTTP){
  返回{
    链接:功能(范围,元素,ATTRS){
      $ http.get('template.html'),然后(功能(结果){
        element.replaceWith($编译(result.data)(范围));
      });
    }
  }
})

I have a tab page with multiple tabs that once clicked on call a service to return some data. Some of that data returns html forms and are very random. I want to collect those values that are entered and send the data via a service back to the server. The problem I have is that I can't get the data from the input elements in the html I'm creating dynamically.

I've created a Plunker to show what the issue is. Note that the html value can change at any time so hard-coding the html won't work. Here the code from the plunker, but please look at the plunker for the best view of whats going on.

app.js

var app = angular.module('plunker', []);

app.controller('MainCtrl', function($scope, $sce, $compile) {
    $scope.name = 'World';
    $scope.html = "";

    $scope.htmlElement = function(){
        var html = "<input type='text' ng-model='html'></input>";
        return $sce.trustAsHtml(html);
    }

});

index.html

<!DOCTYPE html>
<html ng-app="plunker">

  <head>
    <meta charset="utf-8" />
    <title>AngularJS Plunker</title>
    <script>document.write('<base href="' + document.location + '" />');</script>
    <link rel="stylesheet" href="style.css" />
    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.2.0-rc.3/angular.js"></script>
    <script src="app.js"></script>
  </head>

  <body ng-controller="MainCtrl">
    <p>Hello {{name}}!</p>

    <div ng-bind-html="htmlElement()"></div>

    {{html}}

  </body>

</html>

解决方案

One solution would be to use ngInclude with $templateCache, as demonstrated in this Plunker.

There are a couple things to note.

The first is that you can fetch your template using a service and add it to the $templateCache, as described here (example copied):

myApp.service('myTemplateService', ['$http', '$templateCache', function ($http, $templateCache) {
  $http(/* ... */).then(function (result) {
    $templateCache.put('my-dynamic-template', result);
  });
}]);

Then you can include it in your template as follows:

<div ng-include="'my-dynamic-template'"></div>

ngInclude will allow databinding on the html string, so you don't need ngBindHtml.

The second is that, as ngInclude creates a new scope, accessing the html property outside of the newly created scope won't work properly unless you access it via an object on the parent scope (e.g. ng-model="data.html" instead of ng-model="html". Notice that the $scope.data = {} in the parent scope is what makes the html accessible outside of the ngInclude scope in this case.

(See this answer for more on why you should always use a dot in your ngModels.)


Edit

As you pointed out, the ngInclude option is much less useful when using a service to return the HTML.

Here's the edited plunker with a directive-based solution that uses $compile, as in David's comment above.

The relevant addition:

app.directive('customHtml', function($compile, $http){
  return {
    link: function(scope, element, attrs) {
      $http.get('template.html').then(function (result) {
        element.replaceWith($compile(result.data)(scope));
      });
    }
  }
})

这篇关于绑定Angularjs到新创建的html元素动态的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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