AngularJS如何dynamic添加HTML并绑定到控制器

我刚刚开始使用angularJS,并努力弄清楚我正在尝试做的适当的架构。 我有一个单页的应用程序,但url总是应该保持不变 ; 我不希望用户能够导航到超出根目录的任何路由。 在我的应用程序,有一个主要的div将需要主持不同的意见。 当访问新视图时,我希望它接pipe主div上的显示。 以这种方式加载的视图可能会被丢弃或被隐藏在DOM中 – 我有兴趣了解每种方式如何工作。

我想出了一个我正在尝试做的事情的粗略的例子。 在这个Plunk中看到工作的例子。 基本上我想dynamic地加载HTML到DOM,并有标准的angularJS控制器能够钩入新的HTML。 有没有更好/更简单的方法来做到这一点比使用我在这里的自定义指令,并使用$ compile()挂钩angular? 也许有一些像路由器,但不需要URL有变化来操作?

以下是我目前使用的特殊指令(从另一个SOpost中获取):

// Stolen from: http://stackoverflow.com/questions/18157305/angularjs-compiling-dynamic-html-strings-from-database myApp.directive('dynamic', function ($compile) { return { replace: true, link: function (scope, ele, attrs) { scope.$watch(attrs.dynamic, function(html) { if (!html) { return; } ele.html((typeof(html) === 'string') ? html : html.data); $compile(ele.contents())(scope); }); } }; }); 

谢谢,

安迪

我会使用内置的ngInclude指令。 在下面的例子中,你甚至不需要写任何javascript。 模板可以很容易地生活在一个远程的url。

这是一个工作演示: http : //plnkr.co/edit/5ImqWj65YllaCYD5kX5E?p=preview

 <p>Select page content template via dropdown</p> <select ng-model="template"> <option value="page1">Page 1</option> <option value="page2">Page 2</option> </select> <p>Set page content template via button click</p> <button ng-click="template='page2'">Show Page 2 Content</button> <ng-include src="template"></ng-include> <script type="text/ng-template" id="page1"> <h1 style="color: blue;">This is the page 1 content</h1> </script> <script type="text/ng-template" id="page2"> <h1 style="color:green;">This is the page 2 content</h1> </script> 

还有另一种方式

  1. 第1步:创build一个sample.html文件
  2. 第二步:用id = loadhtml创build一个div标签例如: <div id="loadhtml"></div>
  3. 步骤3:在任何控制器中

      var htmlcontent = $('#loadhtml '); htmlcontent.load('/Pages/Common/contact.html') $compile(htmlcontent.contents())($scope); 

这将在当前页面加载一个html页面

对于像我这样的人来说,他们没有可能使用angular度指令,而是在angular度范围之外“卡住”,所以这里可能对你有帮助。

在Web上和angular度文档上search几个小时之后,我创build了一个编译HTML的类,将它放在一个目标中,并将其绑定到一个作用域( $rootScope如果该元素没有$scope

 /** * AngularHelper : Contains methods that help using angular without being in the scope of an angular controller or directive */ var AngularHelper = (function () { var AngularHelper = function () { }; /** * ApplicationName : Default application name for the helper */ var defaultApplicationName = "myApplicationName"; /** * Compile : Compile html with the rootScope of an application * and replace the content of a target element with the compiled html * @$targetDom : The dom in which the compiled html should be placed * @htmlToCompile : The html to compile using angular * @applicationName : (Optionnal) The name of the application (use the default one if empty) */ AngularHelper.Compile = function ($targetDom, htmlToCompile, applicationName) { var $injector = angular.injector(["ng", applicationName || defaultApplicationName]); $injector.invoke(["$compile", "$rootScope", function ($compile, $rootScope) { //Get the scope of the target, use the rootScope if it does not exists var $scope = $targetDom.html(htmlToCompile).scope(); $compile($targetDom)($scope || $rootScope); $rootScope.$digest(); }]); } return AngularHelper; })(); 

它涵盖了我所有的情况,但是如果您发现我应该添加的东西,请随时发表评论或编辑。

希望它会有所帮助。

我需要加载几个模板后执行一个指令,所以我创build了这个指令:

 utilModule.directive('utPreload', ['$templateRequest', '$templateCache', '$q', '$compile', '$rootScope', function($templateRequest, $templateCache, $q, $compile, $rootScope) { 'use strict'; var link = function(scope, element) { scope.$watch('done', function(done) { if(done === true) { var html = ""; if(scope.slvAppend === true) { scope.urls.forEach(function(url) { html += $templateCache.get(url); }); } html += scope.slvHtml; element.append($compile(html)($rootScope)); } }); }; var controller = function($scope) { $scope.done = false; $scope.html = ""; $scope.urls = $scope.slvTemplate.split(','); var promises = []; $scope.urls.forEach(function(url) { promises.add($templateRequest(url)); }); $q.all(promises).then( function() { // SUCCESS $scope.done = true; }, function() { // FAIL throw new Error('preload failed.'); } ); }; return { restrict: 'A', scope: { utTemplate: '=', // the templates to load (comma separated) utAppend: '=', // boolean: append templates to DOM after load? utHtml: '=' // the html to append and compile after templates have been loaded }, link: link, controller: controller }; }]); 
 <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.3.15/angular.min.js"></script> <div class="container-fluid" ut-preload ut-append="true" ut-template="'html/one.html,html/two.html'" ut-html="'<my-directive></my-directive>'"> </div> 

看看这个例子是否提供了任何澄清。 基本上你可以configuration一组路线,并根据路线包含部分模板。 在主index.html中设置ng-view可以让你注入这些部分视图。

configuration部分如下所示:

  .config(['$routeProvider', function($routeProvider) { $routeProvider .when('/', {controller:'ListCtrl', templateUrl:'list.html'}) .otherwise({redirectTo:'/'}); }]) 

将局部视图注入主模板的入口点是:

 <div class="container" ng-view=""></div>