Подтвердить что ты не робот

Связывает Angularjs с новым элементом html динамически

У меня есть закладка с несколькими вкладками, которые однажды нажали на вызов службы, чтобы вернуть некоторые данные. Некоторые из этих данных возвращают html-формы и очень случайны. Я хочу собрать те значения, которые были введены, и отправить данные через службу обратно на сервер. Проблема в том, что я не могу получить данные из входных элементов в html, который я создаю динамически.

Я создал Plunker, чтобы показать, в чем проблема. Обратите внимание, что значение html может измениться в любое время, поэтому жесткое кодирование html не будет работать. Вот код от плункера, но, пожалуйста, посмотрите на плункер, чтобы получить лучший обзор того, что происходит.

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>
4b9b3361

Ответ 1

Одним из решений было бы использовать ngInclude с $templateCache, как показано в этом Plunker.

Есть несколько вещей, которые нужно отметить.

Во-первых, вы можете получить свой шаблон с помощью службы и добавить его в $templateCache, как описано здесь (пример скопирован):

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

Затем вы можете включить его в свой шаблон следующим образом:

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

ngInclude позволит привязывать данные к строке html, поэтому вам не нужен ngBindHtml.

Во-вторых, поскольку ngInclude создает новую область, доступ к свойству html за пределами вновь созданной области действия не будет работать должным образом, если вы не получите доступ к нему через объект в родительской области (например, ng-model="data.html" вместо ng-model="html". Обратите внимание, что $scope.data = {} в родительской области - это то, что делает html доступным вне области ngInclude в этом случае.

(см. этот ответ для получения дополнительной информации о том, почему вы всегда должны использовать точку в своих ngModels.)


Edit

Как вы указали, опция ngInclude гораздо менее полезна при использовании службы для возврата HTML.

Здесь отредактированный plunker с директивным решением, которое использует компиляцию $, как в комментарии Дэвида выше.

Соответствующее дополнение:

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

Ответ 2

Основываясь на ответе Сары, я создал структуру для размещения директивы

.directive('dynamic', function(AmazonService, $compile) {
  return {
    restrict: 'E',
    link: function(scope, element, attrs) {
      AmazonService.getHTML()
     .then(function(result){
       element.replaceWith($compile(result.data)(scope));
     })
     .catch(function(error){
       console.log(error);
     });
   }
 };
});

И в html:

<dynamic></dynamic>

Спасибо, Сара, очень помогло!!!

Ответ 3

У меня есть таблица dinamyc с некоторыми ng-repeat, тогда, когда я попытался заполнить один столбец функцией обратного вызова javascript, он дает мне только текст html, например

<td class="tableList_"+myValue> "span class=someclass> some_text /span>" </td>
<td class="tableList_"+myValue> "span class=someclass> some_text /span>" </td>
<td class="tableList_"+myValue> "span class=someclass> some_text /span>" </td>

Итак, я решил проблему с jquery:

$(".tableListFilas td").each(function(){
   var td_class = $(this).attr("class");
     if(td_class == 'tableList_'+titulo)
     {
       **var toExtraHtml = $(this).text();**
       **$(this).html(toExtraHtml);**
     }
});

тогда конечный результат был хорошим:

<td class="tableList_COLORS"> <span class=someclass>some_text</span> </td>
<td class="tableList_COLORS"> <span class=someclass>some_text</span> </td>
<td class="tableList_COLORS"> <span class=someclass>some_text</span> </td>