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

时间:2013-11-07 20:24:21

标签: javascript angularjs

我刚刚开始使用angularJS并努力找出适合我正在尝试的架构。我有一个单页应用,但网址应始终保持不变;我不希望用户能够导航到root之外的任何路由。在我的应用程序中,有一个主要div需要托管不同的视图。访问新视图时,我希望它接管主div中的显示。以这种方式加载的视图可以丢弃或隐藏在DOM中 - 我很想知道每个视图的工作原理。

我想出了一个粗略的工作示例,说明我正在尝试做什么。 See working example here in this Plunk.基本上我想动态地将HTML加载到DOM中,并让标准的angularJS控制器能够挂钩到新的HTML中。有没有更好/更简单的方法来做到这一点,而不是使用我在这里的自定义指令并使用$ compile()来连接到角度?也许有点像路由器,但是不需要URL有变化才能运行?

这是我到目前为止使用的特殊指令(取自另一个SO帖子):

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

谢谢,

安迪

5 个答案:

答案 0 :(得分:64)

我会使用内置的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 :(得分:17)

还有另一种方法

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

        var htmlcontent = $('#loadhtml ');
        htmlcontent.load('/Pages/Common/contact.html')
        $compile(htmlcontent.contents())($scope);
    
  4. 这将在当前页面中加载html页面

答案 2 :(得分:12)

对于像我这样的人,他们没有可能使用角度指令,并且被困在&#34;在角度范围之外,这里有一些可能对你有用的东西。

在网上和角度文档上搜索了几个小时后,我创建了一个编译HTML的类,将其放在目标中,并将其绑定到范围($rootScope,如果没有{{1} }对于那个元素)

$scope

它涵盖了我的所有案例,但如果您发现我应该添加的内容,请随时发表评论或编辑。

希望它会有所帮助。

答案 3 :(得分:2)

查看this example是否提供了任何说明。基本上,您配置一组路由并包含基于路由的部分模板。在主index.html中设置ng-view允许您注入这些部分视图。

配置部分如下所示:

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

将部分视图注入主模板的输入点是:

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

答案 4 :(得分:2)

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

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>