Angular JS Directive在表达式中加载

时间:2016-05-19 12:08:57

标签: angularjs angular2-directives

我是Angular的新手,已经找到了大量关于指令和嵌套的资源,但似乎无法让这个简单的例子起作用。所以基本上我正在制作一个tabset,我有一个HTML模板:

tabset.html

<div>
    <ul>
        <li ng-repeat="tab in tabset.tabs" ng-class="{active:tabset.current()==$index}">
            <a href ng-click="tabset.current($index)">{{tab}}</a>
        </li>
    </ul>
    <div>
        <div ng-repeat="pane in tabset.panes">
            <div ng-show="tabset.current()==$index">
                {{pane.contents}}
            </div>
        </div>
    </div>
</div>

搜索表单模板:

search-form.html

<div>
    <form name="ytSearch" ng-submit="YTCtrl.submit()" novalidate>
        <label for="search_box">Search For: </label>
        <input id="search_box" ng-model="YTCtrl.searchString"/>
        <br>
        <label for="location">Location: </label>
        <input id="location" ng-model="YTCtrl.location"/>
        within
        <input type="numeric" value="100" ng-model="YTCtrl.locationRadius" />
        <select ng-model="YTCtrl.locationUnit">
            <option value="ft">Feet</option>
            <option value="m">Meters</option>
            <option value="mi">Miles</option>
            <option value="km">Kilometers</option>
        </select>
        <br>
        <label for="search_order">Sort By: </label>
        <select id="search_order" ng-model="YTCtrl.order">
            <option value="relevance">Relevance</option>
            <option value="date">Date</option>
            <option value="rating">Rating</option>
        </select>
        <br>
        <button id="search">
            Search
        </button>
    </form>
</div>

一个简单的app文件,带有2个指令来处理每个模板:

app.js

(function() {
    angular.module("JHYT", [])
        .directive("sidebarTabset", function($compile) {
            return {
                restrict : 'E',
                templateUrl : 'tabset.html',
                controller : function($scope, $compile, $http) {
                    this._current = 0;
                    this.current = function(i) {
                        if (i != null)
                            this._current = i;
                        return this._current;
                    };
                    this.tabs = ['Search', 'Favorite'];
                    this.panes = [{
                        contents : "<search-form></search-form>"
                    }, {
                        contents : "Favorite Pane"
                    }];
                },
                controllerAs : 'tabset',
            };
        }).
        directive("searchForm", function() {
            return {
                restrict : 'E',
                templateUrl : 'search-form.html',
                controller : function($scope, $compile, $http) {
                    this.searchString = '';
                    this.location = '';
                    this.locationRadius = '';
                    this.locationUnit = 'mi';
                    this.order = 'relevance';
                    this.submit = function() {
                        console.log("Submit");
                    };
                },
                controllerAs : 'YTCtrl',
            }
        });
})();

正如您可能已经知道的那样,我们的想法是能够将JSON对象发送到tabset(可能通过服务)并让它构建一个动态tabset,它实际上与我预期的完全相同。不起作用的是,在第一个选项卡中,未处理内容<search-form></search-form>,并且标记在内容区域中呈现为纯文本。

由于这是一个tabset,“child”不需要“parent”中的任何内容,搜索表单和选项卡本身没有作用域依赖关系。在看到嵌套结构的一些例子后,我尝试使用链接和编译函数,但似乎无法使用它们。

如何处理该变量的内容以便使用其模板呈现元素指令?

编辑:

@sielakos给了我正是我所希望的,这是一种可重复使用的方法。

我在我的模块中添加了一个名为compile的指令,它添加了一个包装器以允许我使用纯文本:

.directive("compile", function($compile){
            return {
                restrict: 'A',
                link: function(scope, element, attr){
                    attr.$observe("compile", function(str){
                        var compiled = $compile("<div>"+str+"</div>")(scope);
                        jQuery(element).replaceWith(compiled);
                    })
                }
            }
        })

我更改了我的tabset以使用此指令:

<div>
    <ul>
        <li ng-repeat="tab in tabset.tabs" ng-class="{active:tabset.current()==$index}">
            <a href ng-click="tabset.current($index)">{{tab}}</a>
        </li>
    </ul>
    <div>
        <div ng-repeat="pane in tabset.panes">
            <div ng-show="tabset.current()==$index">
                <div compile="{{pane.contents}}"></div>
            </div>
        </div>
    </div>
</div>

1 个答案:

答案 0 :(得分:0)

如果您希望像使用模板一样使用它,则需要使用$compile服务编译字符串。否则,它将被视为普通字符串并按原样显示。

以下是如何在指令中使用它的示例:

var compiled = $compile(str)(scope);
element.empty();
element.append(compiled); 

如果你希望你能看到这个小提琴更复杂的例子: https://jsfiddle.net/x78uuwp2/

这里我创建了一个简单的编译指令,它使用字符串编译它并将其作为元素体添加到当前作用域。