2013-02-13 3 views
29

Я пытаюсь поместить некоторую угловую строку шаблона js внутри элемента и ожидать выполненный результат. Но этого не происходит.Вставьте угловую строку шаблона js внутри элемента

HTML

<div ng-controller="testController"> 
    <div ng-bind-html-unsafe="fruitsView"></div> 
</div> 

Контроллер:

function filterController($scope){ 
    ... 
    $scope.arr = ["APPLE", "BANANA"]; 
    $scope.fruitsView = '<div><p ng-repeat="each in arr">{{each}}</p></div>'; 
} 

выводе просто {{each}}.

Так как я могу вставить угловую строку шаблона js (здесь $scope.fruitsView) внутри элемента?

Для этого я сделал fiddle.

+3

Почему вы генерируете HTML-код с вашего контроллера? –

+0

Вы могли все это решить? –

+0

Мой прецедент для этой проблемы: я использую стороннюю библиотеку (брошюру), где я хочу вставить некоторые элементы управления, которые реагируют на изменения в области углов. Я бы хотел избежать создания элементов с использованием API-интерфейсов vanilla и изменить их с помощью '$ scope. $ Observ', поскольку это в основном то же самое, что просто регистрировать обычных прослушивателей событий. – fredrikekelund

ответ

95

В этом случае вы не хотите просто «вставлять HTML», но скомпилируйте его. Вы можете создать узлы DOM, используя службу $compile.

var tpl = $compile('<div><p ng-repeat="each in arr">{{each}}</p></div>')(scope); 

Как вы можете видеть, $compile возвращает функцию, которая принимает объект области видимости в качестве параметра, против которого вычисляется код. Полученное содержимое может быть вставлено в DOM с element.append(), например.

Важное примечание: Но при каких обстоятельствах делает любой DOM-кода, связанного с не принадлежат в контроллере. Правильное место всегда директива. Этот код можно легко ввести в директиву, но мне интересно, почему вы программно вставляете HTML вообще.

Можете ли вы пролить свет здесь, чтобы я мог предоставить более конкретный ответ?

Update

Предполагая, что ваши данные поступают от службы:

.factory('myDataService', function() { 
    return function() { 
    // obviously would be $http 
    return [ "Apple", "Banana", "Orange" ]; 
    }; 
}); 

И ваш шаблон приходит от службы

.factory('myTplService', function() { 
    return function() { 
    // obviously would be $http 
    return '<div><p ng-repeat="item in items">{{item}}</p></div>'; 
    }; 
}); 

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

.directive('showData', function ($compile) { 
    return { 
    scope: true, 
    link: function (scope, element, attrs) { 
     var el; 

     attrs.$observe('template', function (tpl) { 
     if (angular.isDefined(tpl)) { 
      // compile the provided template against the current scope 
      el = $compile(tpl)(scope); 

      // stupid way of emptying the element 
      element.html(""); 

      // add the template content 
      element.append(el); 
     } 
     }); 
    } 
    }; 
}); 

Тогда из вашего зрения:

<div ng-controller="MyCtrl"> 
    <button ng-click="showContent()">Show the Content</button> 
    <div show-data template="{{template}}"></div> 
</div> 

И в контроллере, вы просто связать его вместе:

.controller('MyCtrl', function ($scope, myDataService, myTplService) { 
    $scope.showContent = function() { 
    $scope.items = myDataService(); // <- should be communicated to directive better 
    $scope.template = myTplService(); 
    }; 
}); 

И это все должны работать вместе!

PS: все это предполагает, что ваш шаблон поступает с сервера. Если это не так, то ваш шаблон должен находиться в директиве, что упрощает работу.

+0

Я хочу вставить список (тот же шаблон списка в моем вопросе) на странице, когда пользователь нажимает на элемент. Можем ли мы справиться с этим вариантом использования, не выполняя операции dom в контроллере? – rajkamal

+0

+ rajkamal Абсолютно! Таким образом, я могу обновить свой ответ с помощью более конкретного кода, является ли элемент клика таким же, как тот, в который материал вставлен или он другой? –

+0

его другой .. – rajkamal

Смежные вопросы